Java 8 Stream 中的 forEach 与 forEachOrdered
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32797579/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
forEach vs forEachOrdered in Java 8 Stream
提问by gstackoverflow
I understand that these methods differ the order of execution but in all my test I cannot achieve different order execution.
我知道这些方法的执行顺序不同,但在我的所有测试中,我无法实现不同的顺序执行。
Example:
例子:
System.out.println("forEach Demo");
Stream.of("AAA","BBB","CCC").forEach(s->System.out.println("Output:"+s));
System.out.println("forEachOrdered Demo");
Stream.of("AAA","BBB","CCC").forEachOrdered(s->System.out.println("Output:"+s));
Output:
输出:
forEach Demo
Output:AAA
Output:BBB
Output:CCC
forEachOrdered Demo
Output:AAA
Output:BBB
Output:CCC
Please provide examples when 2 methods will produce different outputs.
请提供两种方法会产生不同输出的示例。
采纳答案by Tunaki
Stream.of("AAA","BBB","CCC").parallel().forEach(s->System.out.println("Output:"+s));
Stream.of("AAA","BBB","CCC").parallel().forEachOrdered(s->System.out.println("Output:"+s));
The second line will always output
第二行总是会输出
Output:AAA
Output:BBB
Output:CCC
whereas the first one is not guaranted since the order is not kept. forEachOrdered
will processes the elements of the stream in the order specified by its source, regardless of whether the stream is sequential or parallel.
而第一个没有保证,因为没有保留订单。forEachOrdered
将按照其源指定的顺序处理流的元素,无论流是顺序的还是并行的。
Quoting from forEach
Javadoc:
引用forEach
Javadoc:
The behavior of this operation is explicitly nondeterministic. For parallel stream pipelines, this operation does not guarantee to respect the encounter order of the stream, as doing so would sacrifice the benefit of parallelism.
此操作的行为明显是不确定的。对于并行流管道,此操作不保证遵守流的遇到顺序,因为这样做会牺牲并行性的好处。
When the forEachOrdered
Javadoc states (emphasis mine):
当forEachOrdered
Javadoc 声明(强调我的)时:
Performs an action for each element of this stream, in the encounter order of the streamif the stream has a defined encounter order.
如果流具有定义的遇到顺序,则按流的遇到顺序对此流的每个元素执行操作。
回答by Tagir Valeev
Although forEach
shorter and looks prettier, I'd suggest to use forEachOrdered
in every place where order matters to explicitly specify this. For sequential streams the forEach
seems to respect the order and even stream API internal code usesforEach
(for stream which is known to be sequential) where it's semantically necessary to use forEachOrdered
! Nevertheless you may later decide to change your stream to parallel and your code will be broken. Also when you use forEachOrdered
the reader of your code sees the message: "the order matters here". Thus it documents your code better.
虽然forEach
更短而且看起来更漂亮,但我建议forEachOrdered
在每个顺序很重要的地方使用明确指定这一点。对于顺序流,forEach
似乎尊重顺序,甚至流 API 内部代码使用forEach
(对于已知是顺序的流),在语义上必须使用forEachOrdered
!尽管如此,您稍后可能决定将您的流更改为并行,并且您的代码将被破坏。此外,当您使用forEachOrdered
代码阅读器时,会看到以下消息:“此处的顺序很重要”。因此它可以更好地记录您的代码。
Note also that for parallel streams the forEach
not only executed in non-determenistic order, but you can also have it executed simultaneously in different threads for different elements (which is not possible with forEachOrdered
).
还要注意,对于并行流,forEach
不仅以非确定性顺序执行,而且您还可以让它在不同线程中针对不同元素同时执行(这在 中是不可能的forEachOrdered
)。
Finally both forEach
/forEachOrdered
are rarely useful. In most of the cases you actually need to produce some result, not just side-effect, thus operations like reduce
or collect
should be more suitable. Expressing reducing-by-nature operation via forEach
is usually considered as a bad style.
最后两个forEach
/forEachOrdered
很少有用。在大多数情况下,您实际上需要产生一些结果,而不仅仅是副作用,因此类似reduce
or 的操作collect
应该更合适。通过表达自然减少操作forEach
通常被认为是一种糟糕的风格。
回答by Sushil Mittal
forEach()method performs an action for each element of this stream. For parallel stream, this operation does not guarantee to maintain order of the stream.
forEach()方法为此流的每个元素执行一个操作。对于并行流,此操作不保证保持流的顺序。
forEachOrdered()method performs an action for each element of this stream, guaranteeing that each element is processed in encounter order for streams that have a defined encounter order.
forEachOrdered()方法为此流的每个元素执行一个操作,保证每个元素都按遇到顺序处理,流具有定义的遇到顺序。
take below example:
以下面的例子为例:
String str = "sushil mittal";
System.out.println("****forEach without using parallel****");
str.chars().forEach(s -> System.out.print((char) s));
System.out.println("\n****forEach with using parallel****");
str.chars().parallel().forEach(s -> System.out.print((char) s));
System.out.println("\n****forEachOrdered with using parallel****");
str.chars().parallel().forEachOrdered(s -> System.out.print((char) s));
Output:
输出:
****forEach without using parallel****
****forEach 不使用并行****
sushil mittal
苏尔米塔尔
****forEach with using parallel****
****forEach 使用并行****
mihul issltat
米胡尔伊斯斯塔特
****forEachOrdered with using parallel****
****forEachOrdered 使用并行****
sushil mittal
苏尔米塔尔