2017-05-26 59 views
2

我正在使用Java 8流。Spliterator導致重複鍵異常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 -> "")); 

如果有區別,結果是卡桑德拉結果集,行是卡桑德拉行。

+0

示例問題數據? – weston

+1

你會更好地創建一個[MCVE],這可能會消除cassandra的問題,並且是更一般的,因此對未來訪問者更有用。 – 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)); 

這將需要的值中的一個並且忽略其他在碰撞的情況下您可以選擇其他的合併功能,如附加的兩個值:

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

正如尤金評論,結果被合併到Map在遭遇訂單。

+1

另外..看,那裏有一個'Row',我假設有一些SQL ...並且如果底層結果沒有排序(通常不是),這個(以及for循環)可能會返回不同的結果跑步。但我猜OP是知道的 – Eugene

+0

這是一個卡桑德拉結果集。這些密鑰按添加到Cassandra表中的日期排序。因此,它們是地圖鍵的值不是以數字順序1,2,3,4 ...它們可以是4,1,3,2所以它沒關係 – user432024