2015-09-26 27 views
35

私は、これらのメソッドが実行の順序が異なることを理解しますが、すべてのテストで異なる順序の実行を達成できません。forEach for Java 8 StreamのforEachOrdered

例:

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)); 

出力:2つの方法は、異なる出力を生成するとき

forEach Demo 
Output:AAA 
Output:BBB 
Output:CCC 
forEachOrdered Demo 
Output:AAA 
Output:BBB 
Output:CCC 

は、例を提供してください。

+0

多分、パラレルストリームで試してみてください。 – Pshemo

+0

@Pshemoはそれが可能なオプションですか? – gstackoverflow

+3

不特定の順序は、「異なる順序であることが保証されている」ことを意味するものではありません。それは、*遭遇順序と一致する可能性を常に意味する*未定*を意味します。ビルトインシャッフル機能はありません。 – Holger

答えて

42
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)); 

セカンドラインであろう順序が保たれていないので最初のものがguarantedするれていないのに対し、常に出力

Output:AAA 
Output:BBB 
Output:CCC 

forEachOrderedは、ストリームがシーケンシャルかパラレルかにかかわらず、そのソースによって指定された順序でストリームの要素を処理します。

forEachのJavadocから引用:この操作の動作は、明示的に非決定的である

。並列ストリームパイプラインの場合、この操作はストリームの出会い順を保証するものではありません。並列処理の利点を犠牲にするためです。

forEachOrdered Javadocの状態(強調鉱山):ストリームが定義遭遇順序を有する場合

ストリームの出会いのために、このストリーム、の各要素のためのアクションを実行します。

+6

はい、そうです。 parallelStreamだけが可能ですか? – gstackoverflow

+6

今のところパラレルストリームにのみ適用されていて、それはそうではないと言えますが、未来のストリームを利用するためにいくつかの中間ステップが最適化されれば、将来も破損する可能性があります。ストリームが順序付けられていない場合、ソートは不安定なアルゴリズムを使用する可能性があります。 – the8472

+1

'forEachOrdered'と' parallel'を使うのは意味がありませんか? –

20

forEach短く、きれいに見えますが、私が注文事項はこれを明示的に指定するには、すべての場所でforEachOrderedを使用することをお勧めしたいです。シーケンシャルストリームの場合、forEachは順序を尊重し、API内部コードusesforEach(シーケンシャルであることがわかっているストリームの場合)の意味で使用されます。forEachOrderedを意味的に使用する必要があります。それでもストリームをパラレルに変更するとコードが破損する可能性があります。また、forEachOrderedを使用すると、コードの読者は「注文はここで重要です」というメッセージを表示します。したがって、あなたのコードをより良く文書化します。

forEachは、非決定的な順序で実行されるだけでなく、異なる要素に対して異なるスレッドで同時に実行することもできます(forEachOrderedでは不可能です)。

最後に、forEach/forEachOrderedはほとんど役に立ちません。ほとんどの場合、実際に副作用だけでなく何らかの結果を出す必要があるため、reducecollectのような操作が適しているはずです。 forEachを介して本質的に還元操作を表現することは、通常、悪いスタイルとみなされます。

+6

"最後に両方のforEach/forEachOrderedはめったに役に立たない"。私はもっ​​と同意できませんでした。これらのメソッドは過剰使用されているようです。 – Tunaki

+0

お返事ありがとうございます。実際の生活の例ではありません。私はちょうどJava 8を学ぶ – gstackoverflow

+0

なぜコードに 'forEachOrdered'を使うのが意味的に必要なのですか? – RealSkeptic

関連する問題