Java Reference
In-Depth Information
or of your domain class. This is really simple and suitable if your domain class is a compos-
ite containing different collections.
Of course, if your domain class isn't just a composite and needs to perform some calculation
based on the existing data, then that isn't a suitable route. Even in this situation, though, you
don't necessarily need to build up a custom collector. You can use the
reducing
collector,
which gives us a generic implementation of the reduction operation over streams.
cing
collector.
Example 5-30. Reducing is a convenient way of making custom collectors
String result
=
artists
.
stream
()
.
map
(
Artist:
:
getName
)
.
collect
(
Collectors
.
reducing
(
new
new
StringCombiner
(
", "
,
"["
,
"]"
),
name
->
new
new
StringCombiner
(
", "
,
"["
,
"]"
).
add
(
name
),
StringCombiner:
:
merge
))
.
toString
();
is what you might expect given the name. The key difference is the second argument to
Col-
lectors.reducing
; we are creating a dedicated
StringCombiner
for each element in the
stream. If you are shocked or disgusted at this, you should be! This is highly inefficient and
one of the reasons why I chose to write a custom collector.
Collection Niceties
The introduction of lambda expressions has also enabled other collection methods to be in-
troduced. Let's have a look at some useful changes that have been made to
Map
.
A common requirement when building up a
Map
is to compute a value for a given key. A
classic example of this is when implementing a cache. The traditional idiom is to try and re-
trieve a value from the
Map
and then create it, if it's not already there.
If we defined our cache as
Map<String, Artist> artistCache
and were wanting to look
up artists using an expensive database operation, we might write something like
Example 5-31. Caching a value using an explicit null check