1

I have a nested map with key as Employee name and values as another map with key as company name and value as years of experience like below

Map<String, Map<String, Integer>> map = new HashMap<>();
    Map<String, Integer> innerMap1 = new HashMap<>();
    innerMap1.put("INfosys", 2);
    innerMap1.put("Volvo", 2);
    innerMap1.put("MH", 3);
    innerMap1.put("Piterion", 1);

    Map<String, Integer> innerMap2 = new HashMap<>();
    innerMap2.put("Tata", 2);
    innerMap2.put("Bosch", 1);
    innerMap2.put("Amber", 1);
    innerMap2.put("E2", 1);

    map.put("Rahul", innerMap1);
    map.put("Amrita", innerMap2);

Now my function should return a Map with the employee name as key and total experience as value. How can I do that using java streams (in a single stream)

public Map<String, Integer> getEmployeesWithExp(Map<String, Map<String, Integer>> map) {
    map.entrySet().stream().
                        ...

    return null;
}
1

4 Answers 4

4

There probably are multiple ways but you could collect the entries into a new map and reduce the values of the inner maps to integers, e.g. like this:

Map<String, Integer> result = 
           map.entrySet().stream()
              .collect( 
                  Collectors.toMap(e -> e.getKey(), //or Map.Entry::getKey
                                    e -> e.getValue().values().stream()
                                                      .reduce(0, Integer::sum)));
Sign up to request clarification or add additional context in comments.

Comments

1

This is the first time I tried to use streams with maps, it was quite a good exerxcise, thanks.

I failed to do it in only one stream, though. This solution features one main stream and internal streams.

I used org.apache.commons.lang3.tuple.Pair, by the way.

Map<String, Integer> result = map.entrySet().stream()
        .map(entry -> Pair.of(entry.getKey(), entry.getValue().values().stream().reduce(0, Integer::sum)))
        .collect(Collectors.toMap(Pair::getKey, Pair::getValue));

It answered

 "Amrita" → 5
 "Rahul" → 8

I believe it is correct. :D

Comments

1

This is simple for loops used for solution :-

    Map<String, Integer> finalMap = new HashMap<>();
    for (Entry<String, Map<String, Integer>> entry : map.entrySet()) {
        Integer exp = 0;
        for (Entry<String, Integer> entry2 : entry.getValue().entrySet()) {
            exp += entry2.getValue();
        }
        finalMap.put(entry.getKey(), exp);
    }

Output- {Amrita=5, Rahul=8}

Comments

0

Can be done in simple way:-

Function< Map<String, Integer>,Integer> sumOfValue = (x) ->   x.values().stream().mapToInt(Integer::intValue).sum(); 
stringMapMap.entrySet().stream().collect(Collectors.toMap(
            e-> e.getKey(), e-> sumOfValue.apply(e.getValue())
    ));    

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.