Java Stream:forEach和forEachOrdered之间的区别 [英] Java Stream: difference between forEach and forEachOrdered

查看:1273
本文介绍了Java Stream:forEach和forEachOrdered之间的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

前提:我已经阅读了这个问题和其他人,但我需要一些澄清。

Premise: I've already read this question and others, but I need some clarifications.

我理解 Stream.forEach 方法使处理并行流时的差异(不仅如此),这也解释了为什么这个

I understand that Stream.forEach method makes the difference (not only) when dealing with parallel streams, and this explains why this

//1
Stream.of("one ","two ","three ","four ","five ","six ")
.parallel()
.forEachOrdered(item -> System.out.print(item));

打印

one two three four five six

但是当谈到中间操作时,订单是流并行化时不再保证。所以这段代码

But when it comes to intermediate operations, the order is not guaranteed anymore when stream is parallelized. So this code

//2
Stream.of("one ","two ","three ","four ","five ","six ")
.parallel()
.peek(item -> System.out.print(item))
.forEachOrdered(item -> System.out.print(""));

将打印类似

four six five one three two 

说<$是否正确c $ c> forEachOrdered 方法只影响自己执行中元素的顺序?直观地说,我想 // 1 示例与

Is it correct to say that forEachOrdered method only affects order of elements in its own execution? Intuitively, I'm thinking of //1 example being exactly the same as

//3
Stream.of("one ","two ","three ","four ","five ","six ")
.parallel()
.peek(item -> System.out.print("")) //or any other intermediate operation
.sequential()
.forEach(item -> System.out.print(item));

我的直觉是错的吗?我错过了关于整个机制的一些内容吗?

Is my intuition wrong? Am I missing something about the whole mechanism?

推荐答案

你是对的,因为<$ c $的行动所做的保证是正确的c> forEachOrdered 仅适用于该操作而不适用于其他操作。但是假设这与 .sequential()。forEach(...)相同是错误的。

You are right in that the guarantees made for the action of forEachOrdered only apply to that action and nothing else. But it’s wrong to assume that this is the same as .sequential().forEach(…).

sequential 会将整个流管道转为顺序模式,因此传递给 forEach 的动作将由同一个线程执行,还有前面的 peek 的动作。对于大多数中间操作, parallel sequential 的确切位置是无关紧要的,指定两者都没有意义,因为只有最后一个一个将是相关的。

sequential will turn the entire stream pipeline into sequential mode, thus, the action passed to forEach will be executed by the same thread, but also the preceding peek’s action. For most intermediate operations, the exact placement of parallel or sequential is irrelevant and specifying both makes no sense as only the last one will be relevant.

此外,使用 forEach 时,仍然没有保证订购,即使它没有任何当前实施的后果。 Stream.forEach是否遵循顺序流的遭遇顺序?

Also, there is still no guaranty made about the ordering when using forEach, even if it hasn’t any consequences in the current implementation. This is discussed in "Does Stream.forEach respect the encounter order of sequential streams?"

Stream.forEachOrdered 的文档说明:

The documentation of Stream.forEachOrdered states:


此操作一次处理一个元素,如果存在,则按顺序处理。执行一个元素的操作发生在之前为后续元素执行操作,但对于任何给定元素,操作可以在库选择的任何线程中执行。

This operation processes the elements one at a time, in encounter order if one exists. Performing the action for one element happens-before performing the action for subsequent elements, but for any given element, the action may be performed in whatever thread the library chooses.

因此,动作可能会被不同的线程调用,如 Thread.currentThread()所感知,但不会同时运行。
此外,如果流有遭遇订单,它将在此处重组。 这个答案揭示了遇到订单处理订单的区别

So the action may get invoked by different threads, as perceivable by Thread.currentThread() but not run concurrently. Further, if the stream has an encounter order, it will get reconstituted at this place. This answer sheds some light one the difference of encounter order and processing order.

这篇关于Java Stream:forEach和forEachOrdered之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆