Java Reference
In-Depth Information
Multiple Stream Calls
Rather than chaining the method calls, you could force the evaluation of each function indi-
vidually following a sequence of steps.
Please
don't do this.
Example 3-24
shows our earlier
origins of bands example written in that style. The original example is shown in
Example 3-25
in order to make the comparison easier.
Example 3-24. Stream misuse
List
<
Artist
>
musicians
=
album
.
getMusicians
()
.
collect
(
toList
());
List
<
Artist
>
bands
=
musicians
.
stream
()
.
filter
(
artist
->
artist
.
getName
().
startsWith
(
"The"
))
.
collect
(
toList
());
Set
<
String
>
origins
=
bands
.
stream
()
.
map
(
artist
->
artist
.
getNationality
())
.
collect
(
toSet
());
Example 3-25. Idiomatically chained stream calls
Set
<
String
>
origins
=
album
.
getMusicians
()
.
filter
(
artist
->
artist
.
getName
().
startsWith
(
"The"
))
.
map
(
artist
->
artist
.
getNationality
())
.
collect
(
toSet
());
There are several reasons why the version in
Example 3-24
is worse than the idiomatic,
chained version:
▪ It's harder to read what's going on because the ratio of boilerplate code to actual business
logic is worse.
▪ It's less efficient because it requires eagerly creating new collection objects at each inter-
mediate step.
▪ It clutters your method with meaningless garbage variables that are needed only as inter-
mediate results.
▪ It makes operations harder to automatically parallelize.
Of course, if you're writing your first few
Stream
-based examples, it's perfectly normal to
write code that's a little bit like this. But if you find yourself writing blocks of operations like