Java Reference
In-Depth Information
public
public
Function
<
StringCombiner
,
String
>
finisher
() {
return
return
StringCombiner:
:
toString
;
}
We create our final value from the one remaining container.
There's one aspect of collectors that I haven't described so far:
characteristics
. A character-
istic is a
Set
of objects that describes the
Collector
, allowing the framework to perform
certain optimizations. It's defined through a
characteristics
method.
At this juncture, it's worth reminding ourselves that this code has been written as an educa-
tional exercise and differs a little bit from the internal implementation of the
joining
col-
lector. You may also be thinking that the
StringCombiner
class is looking quite useful.
Don't worry—you don't need to write that either! Java 8 contains a
java.util.StringJoiner
class that performs a similar role and has a similar API.
The main goals of going through this exercise are not only to show how custom collectors
work, but also to allow you to write your own collector. This is especially useful if you have
a domain class that you want to build up from an operation on a collection and none of the
standard collectors will build it for you.
In the case of our
StringCollector
, the container that we were using to collect values was
different from the final value that we were trying to create (a
String
). This is especially
common if you're trying to collect immutable values rather than mutable ones, because oth-
erwise each step of the collection operation would have to create a new value.
It's entirely possible for the final value that you're collecting to be the same as the container
you've been folding your values into all along. In fact, this is what happens when the final
value that you're collecting is a
Collection
, such as with the
toList
collector.
In this case, your
finisher
method needs to do nothing to its container object. More form-
ally, we can say that the
finisher
method is the
identity
function: it returns the value
passed as an argument. If this is the case, then your
Collector
will exhibit the
IDENTITY_FINISH
characteristic and should declare it using the
characteristics
method.
Reduction as a Collector
As you've just seen, custom collectors aren't that hard to write, but if you're thinking about
writing one in order to collect into a domain class it is worth examining the alternatives. The
most obvious is to build one or more collection objects and then pass them into the construct-