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



在java 8流中心,中间操作(如 filtermappeek(的描述为

...此流的元素...

但是,诸如filter之类的流中间操作似乎一次处理并返回单个"元素"。例如,Java 8流操作执行订单问题(请参阅输出(和答案。

filter的API描述是

返回由与给定谓词相匹配的该流元素的流。

但是,Java 8流操作执行订单中提到的代码似乎一次处理并返回单个元素。请阐明API提到的"元素"与代码的单个"元素"的明显处理之间的断开连接。

谢谢。

是的,无状态的中间操作,例如filtermap等流管线中随后的中间操作。调用映射功能后,后者将始终将元素发送到后续操作。

例如:

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

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

我认为您理解这部分,而是您的困惑是为什么在Java Doc中写下了:

返回由匹配该流的元素组成的流 给定的谓词。

"返回流",因为每个中间操作都返回新流

"由元素组成",因为流表示一系列元素,在大多数情况下,有多个元素通过给定的中间操作。

这听起来像是流的元素,但根本不是这种情况。相反,它们可能存储在某些基础集合中或按需生成。


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


作为阅读,布莱恩·戈兹(Brian Goetz(发表了一篇关于引擎盖下的溪流的精彩帖子。这确实介绍了有关流的详细信息,并且有一个很好的动画由Tagir Valeev提供,展示了如何可视化流。

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

请参阅与以下相同的签名:

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

因此,任何此类中间操作都会一次返回流,而不是一个元素,您可以执行所有操作,因为您可以在流上执行。

规格也是如此:

返回由匹配该流的元素组成的流 给定的谓词。

mapfilter中间操作确实在流的每个元素上都执行,但是它们自己返回流。

因此,当我们从上部问题中查看代码时,每个数字1-8将执行过滤器操作,但是它将返回一个新的流,该流仅观察到偶数{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());

没有断开连接,因为像流8流API所说的那样,中间运算符(例如filter(Function<?, Boolean> filteringFunction)(返回流。他们通过在式流中的每个元素上执行给定的filteringFunction并返回一个新的外流来执行此操作,该流程仅观察已过滤为true的元素。

相关内容

  • 没有找到相关文章