Java 8 Streaming: aggregation grouping

I have some problems 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 belonging to this group.

Example: I have the following 3 elements:

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

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

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

I am not sure how to solve this. The most promising thing I've come up with so far:

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

But I'm not sure which function to insert as the last parameter of the merge method. But I do not know if I should use the merge method.

What would be the most elegant implementation for this?

+5
source share
1 answer

You need to add a downstream collector to Collectors.groupingBy(classifier, downstream) . These collectors collect all the elements that have been assigned to the same key. In this case, we just need to sum all the numbers together using Collectors.summingInt(mapper) , and mapper is a function that returns the number to be added.

Assuming this number can be obtained using getter getNumber() , you could:

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

You can use the method link instead of the two lambdas above. If the Element element class, for example, you would have

 Map<String, Integer> result = elements.stream().collect(Collectors.groupingBy( Element::getGroup, Collectors.summingInt(Element::getNumber) )); 
+8
source

Source: https://habr.com/ru/post/1244007/


All Articles