Java 8 Stream中间操作-元素处理

Java 8 Stream intermediate operation - element processing

Java 8 Stream API中,像filtermappeek这样的中间操作的描述被提到为

...elements of this stream...

但是,像 filter 这样的流中间操作似乎一次处理 return 一个个体 'element'。例如,Java 8 stream operations execution order 个问题(见输出)和答案。

filter的API描述为

Returns a stream consisting of the elements of this stream that match the given predicate.

但是,Java 8 stream operations execution order 问题中提到的代码似乎一次处理 return 一个单独的元素。请澄清 API 提到的 'elements' 与代码的单个 'element' 的明显处理之间的脱节。

谢谢。

我认为这里有一些误解,因为过滤器总是 return 流。

签名见下同:

 Stream<T> filter(Predicate<? super T> predicate);

因此,任何此类中间操作 return 都是流而不是一次一个元素,您可以像对流执行一样对它们执行所有操作。

规格也是如此:

Returns a stream consisting of the elements of this stream that match the given predicate.

mapfilter 中间操作确实在流的每个元素上执行,但它们 return 本身就是一个流。

因此,当我们查看上面问题的代码时,将对每个数字 1-8 执行过滤操作,但它将 return 一个仅观察偶数的新流 { 2,4,6,8}.

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8);
List<Integer> twoEvenSquares = numbers.stream().filter(n -> {
    System.out.println("filtering " + n);
    return n % 2 == 0;
}).map(n -> {
    System.out.println("mapping " + n);
    return n * n;
}).limit(2).collect(Collectors.toList());

没有断开连接,因为就像 Stream 8 Stream API 所说的那样,中间运算符像 filter(Function<?, Boolean> filteringFunction) return a Stream。他们通过在 in-stream 和 return 的每个元素上执行给定的 filteringFunction 来执行此操作,一个新的 out-stream 仅观察已过滤到 true 的元素.

是的,filtermap 等无状态中间操作一次处理一个给定的元素,前者要么将其发送到下一个阶段,要么不将其发送到下一个阶段stage是stream pipeline中后续的中间操作。后者总是在调用映射函数后将元素发送到后续操作。

例如:

...
.filter(n -> n % 2 == 0) // retain even numbers
.map(n -> n * n) // square it
...

一次一个元素将通过 filter 操作,如果当前元素满足提供的谓词,则将其传递给 map 操作。

我想你理解这部分,但你的困惑是为什么在 java 文档中写了它:

Returns a stream consisting of the elements of this stream that match the given predicate.

"Returns a stream"因为每个中间操作returns一个新流.

"consisting of the elements" 因为一个流表示一个元素序列,在大多数情况下,有多个元素通过给定的中间操作。

这听起来像是流存储其元素,但事实并非如此。相反,它们可能存储在一些基础集合中或按需生成。


值得注意的是,并非每个中间操作都会一次将一个元素传递到下一阶段。例如,sorted 中间操作缓冲所有元素,直到它看到输入结束,然后将数据发送到后续阶段。


作为阅读材料,Brian Goetz regarding Streams under the hood. This really goes into details about streams and there is a good animation courtesy of Tagir Valeev 的精彩 post 展示了如何可视化流。