2017-05-25 2 views
3

package summaryjava.util.streamの状態次のように:マッピング動作が行われた場合、のJavaストリームステートフルな動作例

ここ
Set<Integer> seen = Collections.synchronizedSet(new HashSet<>()); 
stream.parallel().map(e -> { if (seen.add(e)) return 0; else return e; })... 

ステートフル・ラムダの例は、でmap()のパラメータであります並行して、同じ入力に対する結果はスレッドスケジューリングの違いにより実行ごとに異なることがありますが、ステートレスラムダ式では結果は常に同じになります。

なぜ、これは、セットが同期され、一度に1つの要素しか処理できないので、一貫した結果をもたらさないことは理解できません。並列化によって結果がどのように異なるかを示す方法で上記の例を完了できますか?

答えて

3
List<Integer> numbers = // fill it in with [1, 3, 3, 5] 
List<Integer> collected = numbers.stream().parallel().map(...).collect(Collectors.toList()); 

collectedを含む可能性のいずれかで、[0、0、3、0]又は[0、3、0、0]、中央の2つの素子の第1の処理されたかに応じ。

+0

私は、パラレルストリームがまだエンカウンターオーダーを保持できることを忘れています。ありがとう! – shmosel

+0

Btw、それは見えない要素をゼロにしているので、結果に3つの0があります。 – shmosel

+0

@shmoselうわー、 'if'の方向を後方に持っています。今修正されました。 – Douglas

2

私は(それは私はこれを削除しますしない場合)、これはそれ自体はステートフルとしてカウントかどうかわからないんだけど、map内の状態を持っているなどが悪いに頼ります。 JDK-9で

int[] arr = new int[3]; 
    Stream.of(1, 2, 3) 
      .map(i -> { 
       arr[i] = i + 5; 
       return i * 2; 
      }) 
      .count(); 

    System.out.println(Arrays.toString(arr)); 

ストリームサイズ(flatmap又はfilter)、従ってmapが実行されることはありませんを変更しない操作がないので、これは、ゼロのみを持つ配列を生成します。

+1

興味深い点ですが、質問に直接関係しません。 – shmosel

関連する問題