5

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?

4
  • 4
    you can't have those 4 entries, the keys are the same, it's only 2 Commented Jul 29, 2019 at 9:59
  • @AndrewTobilko I believe the OP meant that the inner Map of key "A" has two entries, as does the inner Map of key "B" Commented Jul 29, 2019 at 10:01
  • correct. The inner maps have the same, but those are different maps, since they are in different entrys of the outer map Commented Jul 29, 2019 at 10:05
  • Possible duplicate of Reducing Map by using Java 8 Stream API Commented Jul 29, 2019 at 10:14

1 Answer 1

8

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)));
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.