Java Reference
In-Depth Information
Joined names: KenJeffDonnaChrisLaynieLi
Joined, delimited names: Ken, Jeff, Donna, Chris, Laynie, Li
Hello Ken, Jeff, Donna, Chris, Laynie, Li. Goodbye.
Grouping Data
Grouping data for reporting purposes is common. For example, you may want to know the average income by gender,
the youngest person by gender, etc. In previous sections, you used the
toMap()
method of the
Collectors
class to
get collectors that can be used to group data in maps. The
groupingBy()
method of the
Collectors
class returns a
collector that groups the data before collecting them in a
Map
. If you have worked with SQL statements, it is similar to
using a “group by” clause. 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)
•
I will discuss the first and second versions. The third version is the same as the second one, except that it lets you
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.
■
the
groupingBy()
method returns a non-concurrent map that has performance overhead when the stream is
processed in parallel. It has a companion method called
groupingByConcurrent()
that returns a concurrent collector
that should be used in parallel stream processing for a better performance.
Tip
In the most generic version, the
groupingBy()
method takes two parameters:
•
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 first version of the
groupingBy()
method returns a collector that collects data into a
Map<K, List<T>>
, where
K
is
the return type of the classifier function and
T
is the type of elements in the input stream. Note that the value of a grouped
key in the map is a list of elements from the stream. The following snippet of code collects the list of people by gender:
A
Map<Person.Gender, List<Person>> personsByGender =
Person.persons()
.stream()
.collect(Collectors.groupingBy(Person::getGender));
System.out.println(personsByGender);
{FEMALE=[(3, Donna, FEMALE, 1962-07-29, 8700.00), (5, Laynie, FEMALE, 2012-12-13, 0.00)],
MALE=[(1, Ken, MALE, 1970-05-04, 6000.00), (2, Jeff, MALE, 1970-07-15, 7100.00), (4, Chris, MALE,
1993-12-16, 1800.00), (6, Li, MALE, 2001-05-09, 2400.00)]}