Java Reference
In-Depth Information
Example 5-19. Using a reduce and a StringBuilder to pretty-print the names of artists
StringBuilder reduced
=
artists
.
stream
()
.
map
(
Artist:
:
getName
)
.
reduce
(
new
new
StringBuilder
(), (
builder
,
name
) -> {
iif
(
builder
.
length
() >
0
)
builder
.
append
(
", "
);
builder
.
append
(
name
);
return
return
builder
;
}, (
left
,
right
) ->
left
.
append
(
right
));
reduced
.
insert
(
0
,
"["
);
reduced
.
append
(
"]"
);
String result
=
reduced
.
toString
();
I had hoped that last refactor would help us make the code clearer. Unfortunately, it seems to
be just as bad as before. Still, let's see what's going on. The
stream
and
map
calls are the
same as in the previous example. Our
reduce
operation builds up the artist names, combined
with
", "
delimiters. We start with an empty
StringBuilder
—the identity of the
reduce
.
Our next lambda expression combines a name with a builder. The third argument to
reduce
takes two
StringBuilder
instances and combines them. Our final step is to add the prefix at
the beginning and the suffix at the end.
For our next refactoring attempt, let's try and stick with reduction but hide the mess—I
mean, abstract away the details—behind a class that we'll call a
StringCombiner
. Imple-
menting this results in
Example 5-20
.
Example 5-20. Using a reduce and a custom StringCombiner to pretty-print the names of
artists
StringCombiner combined
=
artists
.
stream
()
.
map
(
Artist:
:
getName
)
.
reduce
(
new
new
StringCombiner
(
", "
,
"["
,
"]"
),
StringCombiner:
:
add
,
StringCombiner:
:
merge
);
String result
=
combined
.
toString
();
Even though this looks quite different from the previous code example, it's actually doing the
exact same thing under the hood. We're using
reduce
in order to combine names and delim-
iters into a
StringBuilder
. This time, though, the logic of adding elements is being deleg-