2015-08-31 20 views
109
Map<String, String> phoneBook=people.stream() 
            .collect(toMap(Person::getName, Person::getAddress)); 

重複發生時,我得到重複密鑰異常。當使用流生成地圖時忽略重複項

重複發生時,是否可以忽略添加映射的值?

當有重複時,只需繼續忽略該重複密鑰。

+5

只需提供[合併功能](https://docs.oracle.com/javase/8/docs/api/java/util/ stream/Collectors.html#toMap-java.util.function.Function-java.util.function.Function-java.util.function.BinaryOperator-)表示'(舊的,新的) - >舊的'。 –

+0

如果你可以使用它,HashSet會忽略該鍵,如果它已經存在。 – sahitya

+0

@隊長aryabhatta。有沒有可能在hashset – Patan

回答

204

這是可能的使用的Collectors.toMap(keyMapper, valueMapper, mergeFunction)mergeFunction參數:

Map<String, String> phoneBook = 
    people.stream() 
      .collect(Collectors.toMap(
      Person::getName, 
      Person::getAddress, 
      (address1, address2) -> { 
       System.out.println("duplicate key found!"); 
       return address1; 
      } 
     )); 

mergeFunction是,在使用相同的密鑰相關聯的兩個值進行操作的功能。 adress1對應於收集元素時遇到的第一個地址,並且adress2對應於遇到的第二個地址:此lambda只是告訴保留第一個地址並忽略第二個地址。

+0

非常感謝。如果可以在發生重複密鑰時記錄信息,您能否幫助我? – Patan

+2

@Patan我編輯我的帖子,添加一個打印語句,當發現重複 – Tunaki

+1

我很困惑,爲什麼重複的**值**(不是鍵)不允許?以及如何允許重複的值? –

43

JavaDocs說:

如果映射鍵包含重複(根據 Object.equals(Object)),執行 收集操作時IllegalStateException被拋出。如果映射的密鑰可能有 重複項,請改爲使用toMap(Function keyMapper, Function valueMapper, BinaryOperator mergeFunction)

所以你應該使用toMap(Function keyMapper, Function valueMapper, BinaryOperator mergeFunction)來代替。只需提供合併功能,即可確定哪些重複項需要放入地圖。例如,如果您不關心哪一個,請致電

Map<String, String> phoneBook = people.stream() 
    .collect(Collectors.toMap(Person::getName, Person::getAddress, (p1, p2) -> p1)); 
+0

似乎「toMap」不被識別... – bashan

+1

使用'Collectors.toMap'或使一個靜態導入 – alaster