The groupingBy() method from the Collectors class groups the data before collecting them in a Map.
It is similar to using a "group by" clause in SQL.
The groupingBy() method is overloaded and it has three versions:
groupingBy(Function<? super T,? extends K> classifier) groupingBy(Function<? super T,? extends K> classifier, Collector<? super T,A,D> downstream) groupingBy(Function<? super T,? extends K> classifier, Supplier<M> mapFactory, Collector<? super T,A,D> downstream)
The third version can specify a Supplier that is used as the factory to get the Map object.
In the first two versions, the collector takes care of creating the Map object for you.
A classifier that is a function to generate the keys in the map.
A collector that performs a reduction operation on the values associated with each key.
The following code collects the list of people by gender:
Map<Person.Gender, List<Person>> personsByGender = Person.persons() .stream() .collect(Collectors.groupingBy(Person::getGender));
groupingBy() method that lets you perform a reduction operation on the values of each key.
To group people by gender and count the number of people in each group.
The counting() method of the Collectors class returns a Collector to count the number of elements in a stream.
Map<Person.Gender, Long> countByGender = Person.persons() .stream() .collect(Collectors.groupingBy(Person::getGender, Collectors.counting()));
To list a person's name by gender, use the mapping() method from Collectors class.
The signature of the mapping() method is
mapping(Function<? super T,? extends U> mapper, Collector<? super U,A,R> downstream)
The following code groups the names of person by gender:
Map<Person.Gender, String> namesByGender =
Person.persons()
.stream()
.collect(Collectors.groupingBy(Person::getGender,
Collectors.mapping(Person::getName, Collectors.joining(", "))));
The code collects the names for a group in a comma-separated String.
To collect the names in a List, use the collector returned by the toList() method:
Map<Person.Gender, List<String>> namesByGender = Person.persons() .stream() .collect(Collectors.groupingBy(Person::getGender, Collectors.mapping(Person::getName, Collectors.toList())));