2017-05-26 14 views
2

私はJava 8ストリームを使用しています。forループで重複したキー例外が発生するSpliterator

スプライテータを使用してマップに追加すると、重複キー例外が発生しますが、標準のforループを使用しても例外がスローされません。

// This works 
Map<Integer, String> myMap = new HashMap<>(); 
for (Row row : result.result()) { 
    myMap.put(row.get(0, Integer.class), null); 
} 

// This throws exception 
myMap = StreamSupport.stream(result.result().spliterator(), true) 
    .collect(Collectors.toMap(row -> row.get(0, Integer.class), row -> "")); 

それは任意の違いを行った場合、結果は、Cassandraの結果セットであり、行は、Cassandraの行です。

+0

問題データの例ですか? – weston

+1

問題からカッサンドラを排除し、より一般的なので、将来の訪問者に役立つ[MCVE]を作成する方がよいでしょう。 – weston

答えて

4

標準のforループを使用する場合、すでにMapに存在するキーを置くと、古い値が新しい値に置き換えられます。

一方、2つの引数toMapコレクタは、複数の値が同じキーにマッピングされている場合、例外をスローします。

これを回避するには、このような衝突を処理するためにマージ機能を用意する必要があります。例えば

myMap = 
    StreamSupport.stream(result.result().spliterator(), true) 
       .collect(Collectors.toMap(row -> row.get(0, Integer.class), 
              row -> "", 
              (v1,v2) -> v2)); 

これは、のいずれかの値を取り、衝突の場合に他を無視します。ユージンがコメントしたような結果が出会いのためにMapにマージされ、

(v1,v2) -> v1 + ", " + v2 

:あなたは、他のは、このような2つの値を追加するなどの機能を、マージ選択することができます。

+1

また、そこに 'Row'があることを見て、私はいくつかのSQLを仮定します...そして、基本的な結果が順序付けられていないなら(通常はそうではありません)、これは(forループと同様に)走る。しかし、私はOPがそれを認識していると思います – Eugene

+0

それはカサンドラの結果です。キーはカサンドラテーブルに追加された日付でソートされます。だからマップのキーとなる値は数字順1,2,3,4ではなく、4,1,3,2とすることができます – user432024

関連する問題