Converting a Map<String,Map<String,Integer>> to Map<String,Integer> using streams

Proph3cy :

I would like to convert a Map<String,Map<String,Integer>> to a Map<String,Integer> using Streams.

Here's the catch (and why I can't seem to figure it out):

I would like to group my Integer-Values by the Key-Values of the corresponding Maps. So, to clarify:

I have Entries like those:

Entry 1: ["A",["a",1]]

Entry 2: ["B",["a",2]]

Entry 3: ["B",["b",5]]

Entry 4: ["A",["b",0]]

I want to convert that structure to the following:

Entry 1: ["a",3]

Entry 2: ["b",5]

I think that with the Collectors class and methods like summingInt and groupingBy you should be able to accomplish this. I can't seem to figure out the correct way to go about this, though.

It should be noted that all the inner Maps are guaranteed to always have the same keys, either with Integer-value 0 or sth > 0. (e.g. "A" and "B" will both always have the same 5 keys as one another) Everything I've tried so far pretty much ended nowhere. I am aware that, if there wasn't the summation-part I could go with sth like this:

Map<String,Integer> map2= new HashMap<String,Integer>();
                map1.values().stream().forEach(map -> {
                    map2.putAll(map.entrySet().stream().collect(Collectors.toMap(entry -> entry.getKey(), entry -> entry.getValue())));
                });

But how to add the summation part?

Eran :

This should work:

First create a Stream of the entries of all the inner maps, and then group the entries by key and sum the values having the same key.

Map<String,Integer> map2 = 
    map1.values()
       .stream()
       .flatMap(m -> m.entrySet().stream()) // create a Stream of all the entries 
                                            // of all the inner Maps
       .collect(Collectors.groupingBy(Map.Entry::getKey,
                                      Collectors.summingInt(Map.Entry::getValue)));

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=124906&siteId=1