Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/347.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 8流中的forEach vs forEach排序_Java_Foreach_Java 8_Java Stream - Fatal编程技术网

Java 8流中的forEach vs forEach排序

Java 8流中的forEach vs forEach排序,java,foreach,java-8,java-stream,Java,Foreach,Java 8,Java Stream,我知道这些方法的执行顺序不同,但在我所有的测试中,我无法实现不同的执行顺序 例如: 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->Sy

我知道这些方法的执行顺序不同,但在我所有的测试中,我无法实现不同的执行顺序

例如:

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
请提供两种方法产生不同输出的示例

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
将按照源指定的顺序处理流的元素,而不管流是顺序的还是并行的

引用Javadoc:

此操作的行为显然是不确定的。对于并行流管道,此操作不能保证尊重流的相遇顺序,因为这样做会牺牲并行性的好处

当Javadoc声明(强调我的):

如果流具有定义的遭遇顺序,则按照流的遭遇顺序对该流的每个元素执行操作


虽然
forEach
较短且看起来更漂亮,但我建议在订单重要的每个地方使用
forEachOrdered
,以明确说明这一点。对于顺序流,
forEach
似乎尊重顺序,甚至尊重流API内部代码
forEach
(对于已知为顺序的流),在语义上有必要使用
forEachOrdered
!尽管如此,您以后可能会决定将流更改为并行,您的代码将被破坏。另外,当您使用
forEachOrdered
时,代码的读取器会看到这样一条消息:“这里的顺序很重要”。因此,它可以更好地记录您的代码

还请注意,对于并行流,
forEach
不仅以非确定顺序执行,还可以在不同元素的不同线程中同时执行(这在
forEachOrdered
中是不可能的)

最后,
forEach
/
forEachOrdered
两种方法很少有用。在大多数情况下,您实际上需要产生一些结果,而不仅仅是副作用,因此像
reduce
collect
这样的操作应该更合适。通过
forEach
表示按性质减少的操作通常被认为是一种不好的样式。

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));
输出:
如果将forEachOrdered()用于并行流,我们可能会失去并行性的好处

我们知道,在并行编程中,若使用forEach()方法,元素将并行打印。因此,订单将不会固定。但是在forEachOrdered()的使用中,并行流中的顺序是固定的

“AAA”、“BBB”、“CCC”的流。forEachOrdered(s->System.out.println(“输出:+s”); 产量:AAA 产出:BBB
输出:CCC

尝试并行流。@Pshemo这是唯一可能的选项吗?未指定的顺序并不意味着“保证不同的顺序”。它只是意味着未指定,这总是意味着有可能匹配遭遇顺序。没有内置的洗牌功能。是的,你是对的。它是否只适用于并行流?即使它现在只适用于并行流——我不是说它适用于并行流——但如果某些中间步骤得到优化以利用无序流,它在未来仍可能中断,例如,如果流无序,排序可能会使用不稳定的算法。因此,将
forEachOrdered
parallel
一起使用没有意义?@BhushanPatil是的,这是正确的。使用forEachOrdered将按顺序处理元素,然后使用并行流将失去并行性的好处。请建议:“最后,forEach/forEachOrdered都很少有用”。我完全同意。这些方法似乎被过度使用了。为什么语义上有必要在代码中使用
forEachOrdered
。它可以被排序,因此必须以相同的顺序放入结果流中。为什么?在
flatMap
的合同中,您在哪里看到它说它将以相同的顺序放置在输出中?@realpoint,您才是真正的怀疑者
Stream.of(“a”、“b”、“c”).flatMap(s->Stream.of(“1”、“2”、“3”).map(s::concat)).spliterator().hasCharacteristics(spliterator.ORDERED)
返回true,因此必须确定结果流的顺序。如果您觉得JDK文档应该明确地说明这一点,请随意提交一个bug。
****forEach without using parallel****

sushil mittal

****forEach with using parallel****

mihul issltat

****forEachOrdered with using parallel****

sushil mittal