4 回答

TA貢獻1827條經驗 獲得超8個贊
您可以像這樣使用Map#merge :
Map<String, Set<String>> map1; // [key="B";values=["Beryllium", "Boron", "Bromine"]]
Map<String, Set<String>> map2; // [key="B";values=["Bismuth"] key="I";values=["Iron"]]
for (Entry<String, Set<String>> entry : map2.entrySet()) {
? ?map1.merge(entry.getKey(), entry.getValue(), (s1, s2) -> {s1.addAll(s2); return s1;});
}
//map1 = [key="B";values=["Beryllium", "Boron", "Bromine", "Bismuth"] key="I";values=["Iron"]]

TA貢獻1802條經驗 獲得超4個贊
在這種情況下不需要臨時 map1。獲取該字符的集合,如果為空則創建一個新集合。將單詞添加到該集合并放入地圖中:
while (iterator.hasNext()) {
String word = iterator.next();
//some code
Set<String> words = map2.get(word.charAt(0));
if(words == null) {
words = new TreeSet<>();
}
words.add(word);
map2.put(word.charAt(0), words);
}

TA貢獻1886條經驗 獲得超2個贊
使用 merge() 函數時,如果指定的鍵尚未與值相關聯或值為空,則它將鍵與給定值相關聯。否則,即如果鍵與一個值相關聯,它會用給定的重映射函數的結果替換該值。因此,為了不覆蓋舊值,您必須編寫重新映射函數,以便它結合舊值和新值。
為此,請替換此行:
map2.putAll(map1);
和
map1.forEach( (key, value)->{
map2.merge(key, value, (value1,value2) -> Stream.of(value1,value2)
.flatMap(Set::stream)
.collect(Collectors.toSet()));
});
這將遍歷 map1 并將不存在的 echh 鍵添加到 map2 并將其與給定值相關聯,并且對于已經存在的每個鍵,它將舊值和新值組合在一起。
或者你也可以使用Map.computeIfPresent和Map.putIfAbsent
map1.forEach( (key, value)->{
map2.computeIfPresent(key, (k,v) -> Stream.of(v,value).flatMap(Set::stream).collect(Collectors.toSet()));
map2.putIfAbsent(key, value);
});

TA貢獻1828條經驗 獲得超6個贊
Map::compute
可能是你要找的。這為您提供了一種映射任何現有值(如果有的話)的方法,或者如果沒有則提供一個。
例如,在您的情況下,類似以下內容可能就足夠了:
oldMap.compute("B", current -> {
? ? if (current == null) {
? ? ? ? // No existing entry, so use newMap's one
? ? ? ? return newMap.get("B");
? ? } else {
? ? ? ? // There was an existing value, so combine the Sets
? ? ? ? final Set<String> newValue = new HashSet<>(current);
? ? ? ? newValue.addAll(newMap.get("B"));
? ? ? ? return newValue;
? ? }
});
還有分別來自 spring 和 guava 的MultiValueMap
and?Multimap
(如果你可以引入依賴項的話)它們已經用更少的工作覆蓋了這個案例。
添加回答
舉報