2016-11-29 7 views
3

この質問は異なる作業ソート方法のための実行基準はsomhow Java 8 Stream - Filter and foreach method not printing as expected私は、ソート、フィルタおよびJava 8ストリームのマップ方法で働いていますJavaの8ストリーム - フィルタとマップ方法

に関連しています。

Stream.of("d2", "a2", "b1", "b3", "c") 
.sorted((s1, s2) -> { 
    System.out.printf("sort: %s; %s\n", s1, s2); 
    return s1.compareTo(s2); 
}) 
.filter(s -> { 
    System.out.println("filter: " + s); 
    return s.startsWith("a"); 
}) 
.map(s -> { 
    System.out.println("map: " + s); 
    return s.toUpperCase(); 
}) 
.forEach(s -> System.out.println("forEach: " + s)); 

と私が得た出力は次のとおりです:

ソート:次のように上記の質問の答えに指定されているフィルタとマップがどのように機能するかを念頭に置いて キーピングは、私は、ソートの方法を試してみましたA2を; d2 ソート:b1; a2 ソート:b1; d2 ソート:b1; a2 ソート:b3; b1 ソート:b3; d2 ソート:c; b3 ソート:c; D2 フィルタ: マップA2:A2 フィルタ:B1 フィルタ:B3 フィルタ: フィルタC:

D2、今ソート方法は完全なループに対して実行され、その後 forEachのA2フィルタとマップ関数は個々の項目に対して実行されます。 3つはすべて中間関数なので、すべて同じように機能するはずです。 実行命令が正常かどうか私は何が間違っているのか分からない。

+4

どのようにあなたがそれらを見てのすべてがなく、要素を並べ替えることができますか? 'distinct()'と同じです。それはまだ怠惰です - 'forEach'がそこになかったら' sorted'操作は呼び出されません。 – Tunaki

+8

@KaranVermaあなたは本当に多くの質問をしなくてはならないし、いくつかのことを読んでください。 – Eugene

+0

ストリームパイプラインは、forEachが順序付けられていない端末opであるため、ここでの並べ替えを完全に排除できます。以前のバージョンではまったく同じことをしていたと思いますが、積極的に適用されることがあったため最適化が削除されました – the8472

答えて

3

https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html

副作用は、操作をストリーミングする行動パラメーターで

副作用は、一般的には、推奨され、彼らはしばしばとして、無国籍要件の無意識の侵害につながる可能性として他のスレッド安全上の危険性があります。

[...]さらに、これらの影響の順序付けは驚くかもしれません。ストリームソースの遭遇順序と一致する結果を生成するようにパイプラインが制約されている場合(たとえば、IntStream.range(0,5).parallel().map(x -> x*2).toArray() must produce [0, 2, 4, 6, 8]))、マッパー関数が個々の要素に適用される順序や、どのスレッド任意のビヘイビアパラメータが特定の要素に対して実行されます。

enter image description here

+1

そのイメージ...それは面白いと奇妙です – Eugene

3

「それは依存する」。ストリーム操作は、順序が明らかになるとすぐに各ステージがアイテムを放出できるため、インターリーブできます。フィルタリングとマッピングの場合、各項目は処理され、飲み込まれるか、または渡されます。

ソートの場合は、すべてソートアルゴリズムに依存します。ソートが「n-1比較のすべての要素の最小値を見つけ出し、最小値を出し、残りの値と繰り返す」としてソートが実装されていた場合、ソートは実際にフィルタリングとマッピングにインターリーブされます。しかし、あなたの出力を見れば、挿入のソート(バイナリ検索や挿入ポイントの検索ツリー)に似ています。a2/d2は(a2、d2)の結果と比較されます。 b1とa2、b1、b3、d2との間に挿入され、b1はb1と比較され、d2と比較されます。 これはソートのために期待されるO(nlogn)時間をもたらすので意味があります(繰り返し最小限の検索ではO(n^2)と比較されます)が、最後の要素が挿入されるまでは何も出力できません。 つまり、フィルタリングを開始する前にソートを完了する必要があります。

+1

ああ、私の答えを明確にする:あなたは間違って何もしていない。私の答えは、あなたの出力が完全に合理的である理由を受け入れて理解するのに役立ちます。 –

関連する問題