Java Reference
In-Depth Information
created by the groupingBy collector. We need a way of telling the groupingBy collector to
map its list values as it's building up the result.
Each collector is a recipe for building a final value. What we really want is a recipe to give to
our recipe— another collector. Thankfully, the boffins at Oracle have thought of this use case
and provided a collector called mapping .
The mapping collector allows you to perform a map -like operation over your collector's con-
tainer. You also need to tell your mapping collector what collection it needs to store the res-
ults in, which you can do with the toList collector. It's turtles, I mean collectors, all the way
down!
Just like map , this takes an implementation of Function . If we refactor our code to use a
second collector, we end up with Example 5-16 .
Example 5-16. Using collectors to find the names of every album that an artist has produced
public
public Map < Artist , List < String >> nameOfAlbums ( Stream < Album > albums ) {
return
return albums . collect ( groupingBy ( Album: : getMainMusician ,
mapping ( Album: : getName , toList ())));
}
In both of these cases, we've used a second collector in order to collect a subpart of the final
result. These collectors are called downstream collectors. In the same way that a collector is
a recipe for building a final value, a downstream collector is a recipe for building a part of
that value, which is then used by the main collector. The way you can compose collectors
like this makes them an even more powerful component in the streams library.
The primitive specialized functions, such as averagingInt or summarizingLong , are actu-
ally duplicate functionality over calling the method on the specialized stream themselves.
The real motivation for them to exist is to be used as downstream collectors.
Refactoring and Custom Collectors
Although the built-in Java collectors are good building blocks for common operations around
streams, the collector framework is very generic. There is nothing special or magic about the
ones that ship with the JDK, and you can build your own collectors very simply. That's what
we'll look at now.
You may recall when we looked at strings that we could write our example in Java 7, albeit
inelegantly. Let's take this example and slowly refactor it into a proper String -joining col-
lector. There's no need for you to use this code—the JDK provides a perfectly good joining
Search WWH ::




Custom Search