4 回答
TA贡献1827条经验 获得超7个赞
您可以像这样使用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
(如果你可以引入依赖项的话)它们已经用更少的工作覆盖了这个案例。
添加回答
举报