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.
You can concat two maps using Stream.concat then collect using groupingBy map key and value as Set.
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())));
Note: Solution use Java 9+ flatMapping
Or
You can use merge function of map. Here merge map2 data into map1
map2.forEach((key, val) -> map1.merge(key, val, (a, b) -> {a.addAll(b); return a;}));
Output: {ABCD=[AB, BC, CD, EF]}
You make use of the merging function provided to Collectors.toMap that specifies what to do with values of duplicate keys with Streams. Demo
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())));
You can apply a similar approach using Map#merge. Demo
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())));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With