Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 Streaming: Grouping with aggregation

I have some trouble finding a good approach/implementation using the Stream API for the following:

I have a list of elements, each element consisting of a string and an integer. Now I like to group the elements by their string values, and then for each group I like to have the sum of the integer values from the elements that relate to that group.

Example: I have the following 3 elements:

("GroupA", 100) ("GroupA", 50) ("GroupB", 10)

And as a result I like to get a map consisting of the following two (key,value) pairs:

("GroupA, 150) ("GroupB, 10)

I'm not sure how to solve this. The most promising I came up with so far is this:

elements.stream().collect(Collectors.groupingBy(e-> e.getGroup()))
            .merge(group, elementsOfTheGroup, (...));

But I'm not sure what function to insert as the last parameter of the merge method. But I don't know if I should even use the merge method.

What would be the most elegant implementation for this?

like image 472
user3237736 Avatar asked Feb 27 '16 12:02

user3237736


Video Answer


1 Answers

You need to add a downstream collector to Collectors.groupingBy(classifier, downstream). This collectors collects all elements that were classified to the same key. In this case, we just need to sum all the numbers together using Collectors.summingInt(mapper), with the mapper being a function returning the number to sum.

Assuming this number can be retrieved with the getter getNumber(), you could have:

Map<String, Integer> result =
    elements.stream().collect(Collectors.groupingBy(
        e -> e.getGroup(),
        Collectors.summingInt(e -> e.getNumber())
    ));

You could use a method-reference instead of the two lambdas above. If the class of the elements is Element for example, you would have

Map<String, Integer> result =
    elements.stream().collect(Collectors.groupingBy(
        Element::getGroup,
        Collectors.summingInt(Element::getNumber)
    ));
like image 76
Tunaki Avatar answered Sep 18 '22 13:09

Tunaki