合规国际互联网加速 OSASE为企业客户提供高速稳定SD-WAN国际加速解决方案。 广告
## [终端操作](https://lingcoder.gitee.io/onjava8/#/book/14-Streams?id=%e7%bb%88%e7%ab%af%e6%93%8d%e4%bd%9c) 以下操作将会获取流的最终结果。至此我们无法再继续往后传递流。可以说,终端操作(Terminal Operations)总是我们在流管道中所做的最后一件事。 ook/14-Streams?id=%e5%be%aa%e7%8e%af) * `forEach(Consumer)`常见如`System.out::println`作为**Consumer**函数。 * `forEachOrdered(Consumer)`: 保证`forEach`按照原始流顺序操作。 第一种形式:无序操作,仅在引入并行流时才有意义。在[并发编程](https://lingcoder.gitee.io/onjava8/#/24-Concurrent-Programming)章节之前我们不会深入研究这个问题。这里简单介绍下`parallel()`:可实现多处理器并行操作。实现原理为将流分割为多个(通常数目为 CPU 核心数)并在不同处理器上分别执行操作。因为我们采用的是内部迭代,而不是外部迭代,所以这是可能实现的。 `parallel()`看似简单,实则棘手。更多内容将在稍后的[并发编程](https://lingcoder.gitee.io/onjava8/#/24-Concurrent-Programming)章节中学习。 下例引入`parallel()`来帮助理解`forEachOrdered(Consumer)`的作用和使用场景。代码示例: ~~~ // streams/ForEach.java import java.util.*; import java.util.stream.*; import static streams.RandInts.*; public class ForEach { static final int SZ = 14; public static void main(String[] args) { rands().limit(SZ) .forEach(n -> System.out.format("%d ", n)); System.out.println(); rands().limit(SZ) .parallel() .forEach(n -> System.out.format("%d ", n)); System.out.println(); rands().limit(SZ) .parallel() .forEachOrdered(n -> System.out.format("%d ", n)); } } ~~~ 输出结果: ~~~ 258 555 693 861 961 429 868 200 522 207 288 128 551 589 551 861 429 589 200 522 555 693 258 128 868 288 961 207 258 555 693 861 961 429 868 200 522 207 288 128 551 589 ~~~ 为了方便测试不同大小的流,我们抽离出了`SZ`变量。然而即使`SZ`值为14也产生了有趣的结果。在第一个流中,未使用`parallel()`,因此以元素从`rands()`出来的顺序输出结果。在第二个流中,引入`parallel()`,即便流很小,输出的结果的顺序也和前面不一样。这是由于多处理器并行操作的原因,如果你将程序多运行几次,你会发现输出都不相同,这是多处理器并行操作的不确定性造成的结果。 在最后一个流中,同时使用了`parallel()`和`forEachOrdered()`来强制保持原始流顺序。因此,对非并行流使用`forEachOrdered()`是没有任何影响的。