在我的项目中,我正在使用两张地图Map<Character, Set<String>>.
map1 - is temporally holding needed values
map2 - is summing all data from map1 after each loop
例如我得到:
map2 = (B; Beryllium, Boron, Bromine)
map2 = (H; Hellum, Hydrogen, Hafnium)
现在新的map1是:
map1 = (B; Bismuth)
map1 = (O; Oxygen)
在我的代码中,添加氧气作为新条目是可以的,但是为B添加新条目的方法是覆盖值中的现有数据,而只剩下铋。
我的代码:
while (iterator.hasNext()) {
Set<String> words = new TreeSet<>();
String word = iterator.next();
char[] wordChars = word.toCharArray();
//some code
words.add(word);
map1.put(wordChars[i], words);
}
map2.putAll(map1);
我坚决要使用.merge,但是我不知道如何将Sets作为值使用它,而且我不能在concat中使用简单的字符串。
答案 0 :(得分:1)
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
和Multimap
(如果可以引入依赖项),已经可以用较少的工作来解决这种情况。
答案 1 :(得分:1)
在这种情况下,将不需要临时map1。获取该字符的集合,如果为null,则创建一个新集合。将单词添加到该集合中并放入地图中:
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);
}
答案 2 :(得分:1)
您可以像这样使用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"]]
答案 3 :(得分:1)
使用merge()函数时,如果指定的键尚未与某个值关联或该值为null,则它将键与给定的值关联。 否则,即如果键与一个值相关联,它将用给定的重映射函数的结果替换该值。因此,为了不覆盖旧值,您必须编写重新映射函数,以便它将旧值和新值结合在一起。
为此,请替换此行:
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);
});