java - 从流中收集某些元素

标签 java java-8 java-stream

如何从 Stream 中提取两个元素根据他们的立场?例如,我试图从 Stream<String> 中提取元素 0 和 1(这些数字是任意的!) .一个天真的方法是这样的:

List<String> strings = Arrays.asList("s0", "s1", "s2", "s3", "s4");
Consumer<String> c0 = s -> System.out.println("c0.accept(" + s + ")");
Consumer<String> c1 = s -> System.out.println("c1.accept(" + s + ")");
strings.stream().skip(0).peek(c0).skip(1).peek(c1).findAny();

这会产生以下输出:

c0.accept(s0)
c0.accept(s1)
c1.accept(s1)

我明白这是因为s0会进流,遇到skip(0) , 然后 peek(c0) (给出第一行)然后是 skip(1) , 它将跳过这个元素,然后显然从流的开头继续下一个元素。

我以为我可以使用这些消费者来提取字符串,但是 c0将被第二个元素覆盖:

String[] extracted = new String[2];
c0 = s -> extracted[0];
c1 = s -> extracted[1];

编辑:

这些是流的特征:

  • 只有流,没有列表或数组
  • 流可能是无限的
  • 可以制作流sequential

最佳答案

鉴于您的限制,您可以结合 limit()使用这样的自定义收集器:

public static <T, A, R> Collector<T, ?, R> collectByIndex(Set<Integer> wantedIndices, 
                                                          Collector<T, A, R> downstream) {
    class Acc {
        int pos;
        A acc = downstream.supplier().get();
    }
    return Collector.of(Acc::new, (acc, t) -> {
        if(wantedIndices.contains(acc.pos++))
            downstream.accumulator().accept(acc.acc, t);
    }, (a, b) -> {throw new UnsupportedOperationException();}, // combining not supported
       acc -> downstream.finisher().apply(acc.acc));
}

在这里Set<Integer> wantedIndices是包含所需元素索引的集合(不限于 2)。用法:

Set<Integer> wantedIndices = new HashSet<>(Arrays.asList(1, 3));
Stream<String> input = Stream.of("s0", "s1", "s2", "s3", "s4");
List<String> result = input.limit(Collections.max(wantedIndices)+1)
            .collect(collectByIndex(wantedIndices, Collectors.toList()));
// [s1, s3]

关于java - 从流中收集某些元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32481895/

相关文章:

java - 带 double 的 RandomList 不显示随机变量

java - Appium Java,如何使用特定的 pageFactory 要求

java - 匿名类替换为 lambda 表达式

scala - Scala : Compilation error: Cannot resolve overloaded method

java - GWT CSS 选择 : which to use, 何时以及为什么?

java - 1.4 Commons-DBCP 被引入而不是 1.3

java - 将两个不同的对象列表合并为一个具有共享 id 字段的对象列表

java - 使用 lambda 表达式按值类的成员搜索 TreeMap

java - 为什么 .filter 不从我的 Map<String,Object> 中删除空值

Java 8 显示此错误。在封闭作用域中定义的局部变量 itemList 必须是 final 或有效 final