3

I want to merge 2 Maps, but when the key is the same, the values should be appended instead of overwritten.

Let's say

Map<String, Set<String>> map1 = new HashMap<>();
Set<String> set1 = new HashSet<>();
set1.add("AB");
set1.add("BC");
map1.put("ABCD",set1);

Map<String, Set<String>> map2 = new HashMap<>();
Set<String> set2 =new HashSet<>();
set2.add("CD");
set2.add("EF");
map2.put("ABCD",set2);

map1.putAll(map2);

So here the key is same.I know putAll will overwrite the values if key is same

But I am looking for an output like

{ABCD=[AB,BC,CD,ED]}

If someone can help me to resolve, will be so thankful.

4

3 回答 3

5

您可以连接两个地图,然后使用地图键和值作为集合Stream.concat进行收集。groupingBy

Map<String, Set<String>> res = 
       Stream.concat(map1.entrySet().stream(), map2.entrySet().stream())
             .collect(Collectors.groupingBy(e-> e.getKey(),
                                Collectors.flatMapping(e -> e.getValue().stream(), Collectors.toSet())));

注意:解决方案使用 Java 9+flatMapping

或者

您可以使用merge地图的功能。这里将map2数据合并到map1

map2.forEach((key, val) -> map1.merge(key, val, (a, b) -> {a.addAll(b); return a;}));

输出:{ABCD=[AB, BC, CD, EF]}

于 2020-07-25T19:55:16.813 回答
2

您可以使用提供的合并函数来Collectors.toMap指定如何处理 Streams 中重复键的值。演示

final Map<String, Set<String>> map3 = Stream.concat(map1.entrySet().stream(), map2.entrySet().stream())
        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
                (a, b) -> Stream.concat(a.stream(), b.stream()).collect(Collectors.toSet())));

您可以使用类似的方法Map#merge演示

final Map<String, Set<String>> map3 = new HashMap<>(map1);
map2.forEach((key, val) -> map3.merge(key, val,
        (a, b) -> Stream.concat(a.stream(), b.stream()).collect(Collectors.toSet())));
于 2020-07-25T19:57:08.927 回答
1

您可以使用Stream API合并相同键的值,检查是否map2具有相同的键map1并循环它们并将值合并在一起使用addAll()

map1.entrySet().stream().filter(entry -> map2.containsKey(entry.getKey()))
                .forEach(entry -> entry.getValue().addAll(map2.get(entry.getKey())));

,main函数

public static void main(String[] args) {
    Map<String, Set<String>> map1 = new HashMap<>();
    Set<String> set1 = new HashSet<>();
    set1.add("AB");
    set1.add("BC");
    map1.put("ABCD", set1);

    Map<String, Set<String>> map2 = new HashMap<>();
    Set<String> set2 = new HashSet<>();
    set2.add("CD");
    set2.add("EF");
    map2.put("ABCD", set2);

    map1.entrySet()
        .stream()
        .filter(entry -> map2.containsKey(entry.getKey()))
        .forEach(entry -> entry.getValue().addAll(map2.get(entry.getKey())));

    System.out.println(map1);
}

,output

{ABCD=[AB, BC, CD, EF]}
于 2020-07-25T19:54:34.617 回答