Let's say, I have an object Person with fields of type FirstName and LastName. Now I also have a List<Person>
and I like to use streams.
Now I want to generate a Map<FirstName, List<LastName>>
in order to group people with the same first name. How do I go about this without writing much code? My approach so far is
personList
.stream()
.collect(Collectors.groupingBy(
Person::getFirstName,
person -> person.getLastName() // this seems to be wrong
));
but it seems this is the wrong way to assign the value of the map. What should I change? Or should I perhaps use .reduce with new HashMap<FirstName, List<LastName>>()
as initial value and then aggregate to it by putting elements inside?
The groupingBy () method of Collectors class in Java are used for grouping objects by some property and storing results in a Map instance. In order to use it, we always need to specify a property by which the grouping would be performed. This method provides similar functionality to SQL’s GROUP BY clause.
Use a summingInt () as the second argument to groupingBy (). Remember the second argument collects the value-type of the group into the map. Summarizing using grouping by is a useful technique in data analysis. Normally these are available in SQL databases.
Concurrent groupingBy Collector Similar to groupingBy is the groupingByConcurrent collector, which leverages multi-core architectures. This collector has three overloaded methods that take exactly the same arguments as the respective overloaded methods of the groupingBy collector.
GroupingBy Collectors. The Java 8 Stream API lets us process collections of data in a declarative way. The static factory methods Collectors.groupingBy() and Collectors.groupingByConcurrent() provide us with functionality similar to the ‘GROUP BY' clause in the SQL language.
personList.stream()
.collect(Collectors.groupingBy(
Person::getFirstName,
Collectors.mapping(Person::getLastName, Collectors.toList())));
You are looking for a downstream collector with groupingBy
This should work for you :
Map<String, List<String>> map = personList.stream()
.collect(Collectors.groupingBy(Person::getFirstName,
Collectors.mapping(Person::getLastName, Collectors.toList())));
I think you are looking for something like this:
Map<String, Map<String, List>> map = personList.stream()
.collect(groupingBy(Person::getFirstName, groupingBy(Person::getLastName)));
The double grouping gives you a map of a map. That's the trick.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With