Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: groupingBy subvalue as value

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?

like image 803
Phil Avatar asked Oct 18 '18 17:10

Phil


People also ask

What is the use of groupingby method in Java?

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.

How do I sum the value of a group using groupingby?

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.

What is groupingbyconcurrent in Java?

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.

What is groupingby in Java 8 stream?

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.


3 Answers

personList.stream()
          .collect(Collectors.groupingBy(
               Person::getFirstName,
               Collectors.mapping(Person::getLastName, Collectors.toList())));

You are looking for a downstream collector with groupingBy

like image 132
Eugene Avatar answered Oct 20 '22 17:10

Eugene


This should work for you :

Map<String, List<String>> map = personList.stream()
                .collect(Collectors.groupingBy(Person::getFirstName, 
                        Collectors.mapping(Person::getLastName, Collectors.toList())));
like image 45
Naman Avatar answered Oct 20 '22 18:10

Naman


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.

like image 34
Perimosh Avatar answered Oct 20 '22 19:10

Perimosh