Merge list of maps into a single map by summing values
You can collect the entries of your Stream
with a toMap
collector, with a merge function.
public static Map<String, Values> mergeMaps(List<Map<String, Values>> maps) {
return maps.stream()
.flatMap(m -> m.entrySet().stream())
.collect(Collectors.toMap(Map.Entry::getKey,
Map.Entry::getValue,
(v1,v2) -> new Values(v1,v2)));
}
Assuming you have a Values
constructor that takes two Values
instances and creates an instance having the sums of the values.
Of course, you can write the merge function without that constructor. For example:
(v1,v2) -> new Values(v1.getCount()+v2.getCount(),v1.getValue()+v2.getValue())
One more solution with groupingBy:
Map<String, Optional<Values>> collect = list.stream()
.flatMap(map -> map.entrySet().stream())
.collect(groupingBy(Map.Entry::getKey, mapping(Map.Entry::getValue,
reducing((v1, v2) -> new Values(v1.count + v2.count, v1.values + v2.values)))));
Note: values of this map are Optional<Values>
.
If you have null
value on one of your source map like map2.put("ddd", null);
it allows to avoid NullPointerException
and return Optional.empty