从具有满足流条件的第n个元素的Java列表中获取子列表

时间:2015-08-31 11:09:27

标签: java lambda functional-programming java-8 java-stream

我有一个非常简单的用例

给定一个包含A和B的字母列表,我想得到包含前N个B的子列表,例如:

  • f(3,[A A A B A B A B A A])= [A A A B A B A B]
  • f(2,[A A A B A B A B A A])= [A A A B A B]
  • f(1,[A A B A B A])= [A A B]
  • f(0,[A A B A B])= []

通过遵循命令式方法,这相对容易,直到我们找到N Bs,然后获得子列表直到该位置。

但是,我找不到lambda的任何功能解决方案,因为每个节点上的操作似乎独立于其他节点(我认为并行化是有意义的。)

3 个答案:

答案 0 :(得分:2)

如果您的输入是具有快速随机访问权限的List,则可以使用索引流解决您的问题:

public static List<String> f(int n, List<String> input) {
    int fence = IntStream.range(0, input.size())
                         .filter(idx -> input.get(idx).equals("B")) // leave only B's
                         .skip(n-1)
                         .findFirst() // an index of n-th B
                         .getAsInt(); // with throw NoSuchElementException if not enough B's
    return input.subList(0, fence+1);
}

用法示例:

System.out.println(f(3, Arrays.asList("A", "A", "A", "B", "A", "B", "A", "B", "A", "A")));
System.out.println(f(2, Arrays.asList("A", "A", "A", "B", "A", "B", "A", "B", "A", "A")));
System.out.println(f(1, Arrays.asList("A", "A", "A", "B", "A", "B", "A", "B", "A", "A")));

然而,尽管我喜欢Stream API,但我还是必须解决这个问题。

答案 1 :(得分:0)

此代码段完成了这项工作。

public static void main(String[] args) {
    final String input = "A A A B A B A B A A";
    final String[] array = input.split(" ");
    final List<String> list = Arrays.asList(array);
    final List<String> result = getSubList(list, 3);
    System.out.println("Result=" + result);
}

public static List<String> getSubList(final List<String> list, final int limit) {
    final AtomicInteger counter = new AtomicInteger();
    return list.stream()
            .filter(ch -> {
                if (ch.equals("B") && counter.incrementAndGet() == limit) return true;
                return counter.get() < limit;
            })
            .collect(Collectors.toList());
}

答案 2 :(得分:0)

以下是AbacusUtil

的代码
List<String> input = N.asList("A", "A", "A", "B", "A", "B", "A", "B", "A", "A");
List<String> list = Stream.of(input).takeWhile(MutableInt.of(3), (e, cnt) -> cnt.getAndAdd(e.equals("B") ? -1 : 0) > 0).toList();
N.println(list);

声明:我是AbacusUtil的开发者。

相关问题