据我所知,这些方法的执行顺序不同,但在我的测试中,我无法实现不同的订单执行。
示例:
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));
输出:
forEach Demo
Output:AAA
Output:BBB
Output:CCC
forEachOrdered Demo
Output:AAA
Output:BBB
Output:CCC
如果两种方法产生不同的输出,请提供示例。
答案 0 :(得分:66)
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));
第二行将始终输出
Output:AAA
Output:BBB
Output:CCC
由于没有保留订单,因此第一个不能保证。 forEachOrdered
将按照源指定的顺序处理流的元素,无论流是顺序流还是并行流。
引自forEach
Javadoc:
此操作的行为明确是不确定的。对于并行流管道,此操作不保证遵守流的遭遇顺序,因为这样做会牺牲并行性的好处。
当forEachOrdered
Javadoc陈述(强调我的)时:
如果流具有已定义的遭遇顺序,则对此流的每个元素执行操作,按流的遇到顺序。
答案 1 :(得分:25)
虽然forEach
更短,看起来更漂亮,但我建议在订单有效的每个地方使用forEachOrdered
来明确指定。对于顺序流,forEach
似乎尊重顺序,甚至流API内部代码uses forEach
(对于已知为顺序的流),在语义上需要使用{{1} }!不过,您可能稍后决定将您的流更改为并行,您的代码将被破坏。此外,当您使用forEachOrdered
代码的读者时,会看到以下消息:“此处的顺序很重要”。因此,它更好地记录了您的代码。
另请注意,对于并行流,forEachOrdered
不仅以非威慑顺序执行,而且还可以在不同的线程中同时为不同的元素执行(forEach
无法实现)
最后,forEachOrdered
/ forEach
都很少有用。在大多数情况下,您实际上需要产生一些结果,而不仅仅是副作用,因此forEachOrdered
或reduce
等操作应该更合适。通过collect
表达逐渐减少操作通常被认为是一种不好的风格。
答案 2 :(得分:7)
forEach()方法对该流的每个元素执行操作。对于并行流,此操作不能保证维持流的顺序。
forEachOrdered()方法对该流的每个元素执行操作,以确保对具有已定义遇到顺序的流按遇到顺序处理每个元素。
以下面的示例为例:
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));
输出:
**** forEach不使用并行****
苏希尔·米塔尔
**** for每次使用并行****
mihul issltat
**** forEachOrdered使用并行****
苏希尔·米塔尔
答案 3 :(得分:0)
如果我们将 forEachOrdered() 与并行流一起使用,我们可能会失去并行性的好处。
众所周知,如果我们使用 forEach() 方法,并行编程元素将并行打印。所以订单不会固定。但是在并行Streams中使用forEachOrdered()固定顺序。
Stream.of("AAA","BBB","CCC").forEachOrdered(s->System.out.println("输出:"+s)); 输出:AAA 输出:BBB 输出:CCC