Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to flatten List of Maps in java 8

I have requirement where I have list of maps

[{Men=1},{Men=2, Women=3},{Women=2,Boys=4}]

Now I need make it a flatMap such that it looks like

Gender=countOfValues

In the above example the output would be

{Men=3,Women=5,Boys=4}

Currently I have the following code:

private Map<String, Long> getGenderMap(
        List<Map<String, Long>> genderToCountList) {
    Map<String, Long> gendersMap = new HashMap<String, Long>();
    Iterator<Map<String, Long>> genderToCountListIterator = genderToCountList
            .iterator();
    while (genderToCountListIterator.hasNext()) {
        Map<String, Long> genderToCount = genderToCountListIterator.next();
        Iterator<String> genderToCountIterator = genderToCount.keySet()
                .iterator();
        while (genderToCountIterator.hasNext()) {
            String gender = genderToCountIterator.next();
            if (gendersMap.containsKey(gender)) {
                Long count = gendersMap.get(gender);
                gendersMap.put(gender, count + genderToCount.get(gender));
            } else {
                gendersMap.put(gender, genderToCount.get(gender));
            }
        }
    }
    return gendersMap;
}

How do we write this piece of code using Java8 using lambda expressions?

like image 351
user2166328 Avatar asked Nov 05 '15 20:11

user2166328


People also ask

How do I flatten a List in Java 8?

The standard solution is to use the Stream. flatMap() method to flatten a List of Lists. The flatMap() method applies the specified mapping function to each element of the stream and flattens it.

How do you convert a List to map in Java 8?

With Java 8, you can convert a List to Map in one line using the stream() and Collectors. toMap() utility methods. The Collectors. toMap() method collects a stream as a Map and uses its arguments to decide what key/value to use.


1 Answers

I wouldn't use any lambdas for this, but I have used Map.merge and a method reference, both introduced in Java 8.

Map<String, Long> result = new HashMap<>();
for (Map<String, Long> map : genderToCountList)
    for (Map.Entry<String, Long> entry : map.entrySet())
        result.merge(entry.getKey(), entry.getValue(), Long::sum);

You can also do this with Streams:

return genderToCountList.stream().flatMap(m -> m.entrySet().stream())
           .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, Long::sum));
like image 189
Paul Boddington Avatar answered Sep 28 '22 10:09

Paul Boddington