これらのメソッドは実行順序が異なることを理解していますが、すべてのテストで、実行順序を変えることはできません。
例:
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
2つの方法で異なる出力が生成される場合の例を提供してください。
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));
2行目は常に出力されます
Output:AAA
Output:BBB
Output:CCC
一方、順序は保持されないため、最初のものは保証されません。 forEachOrdered
は、ストリームがシーケンシャルかパラレルかに関係なく、ソースで指定された順序でストリームの要素を処理します。
forEach
Javadocからの引用:
この操作の動作は明示的に非決定的です。並列ストリームパイプラインの場合、この操作はストリームの遭遇順序を尊重することを保証しません。そうすると、並列処理の利点が犠牲になります。
forEachOrdered
Javadocの状態(エンファシス鉱山)の場合:
このストリームの各要素に対してアクションを実行します。ストリームの遭遇順序ストリームに遭遇順序が定義されている場合。
forEach
は短く、きれいに見えますが、順序が重要なすべての場所でforEachOrdered
を使用して、これを明示的に指定することをお勧めします。シーケンシャルストリームの場合、forEach
は順序を尊重しているようで、APIの内部コード usesforEach
(シーケンシャルであることがわかっているストリーム) 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));
出力:
****並列を使用しないforEach ****
スシル・ミッタル
****並列を使用したforEach ****
ミフル・イスルタット
**** forEachOrdered with parallel ****
スシル・ミッタル