Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 streams - merging a list of Maps

I'm trying to use a stream of List<Map<String, Integer>> to merge all maps included into one. This is to aggregate multiple request responses into one.

Consider this dataset (using JSON to make it easier to read):

[
    {"field1": 1, "field2": 5},
    {"field2": 6, "field3": 10},
    {"field1": 3, "field4": 15}
]

I want it to result in the following (order does not matter):

{"field1": 4, "field2": 11, "field3": 10, "field4": 15}

I want to sum all keys and combine them into a single map. Is there a nice way to do this with the Stream interface in Java 8?

I discovered Collectors.groupingBy(o -> o, Collectors.counting()), so perhaps I'm on the right lines, I just need to figure out how to actually merge them in advance of this without screwing up the results.

Thanks in advance.

like image 635
whitfin Avatar asked Jul 31 '15 17:07

whitfin


People also ask

How do I merge a List of maps?

We can merge Map collections using the merge() method. This returns a copy of the collection with the remaining collections merged in. We get the same results as the previous example when we run the above code. The merge() method can also be used to merge Map collections.

Can you combine two maps?

If Google recognizes both locations' addresses, create a joint map by entering both addresses into Google Maps' text boxes. Alternatively, find the locations manually on separate pages, then merge them onto a single map.


1 Answers

counting() will just return the number of values that are grouped by the function you apply for each key. If you want to sum them, the downstream collector you are looking for is summingInt (or summingLong if you may have overflows):

import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.summingInt;

...

Map<String, Integer> map =
    list.stream()
        .flatMap(m -> m.entrySet().stream())
        .collect(groupingBy(Map.Entry::getKey, summingInt(Map.Entry::getValue)));
like image 191
Alexis C. Avatar answered Sep 19 '22 23:09

Alexis C.