Java Reference
In-Depth Information
Example 3-13
provides some code that finds the shortest track on an album. In order to make
it easier to see that we've got the right result, I've explicitly listed the tracks on this album in
the code snippet; I'll admit that it's not the best-known album.
Example 3-13. Finding the shortest track with streams
List
<
Track
>
tracks
=
asList
(
new
new
Track
(
"Bakai"
,
524
),
new
new
Track
(
"Violets for Your Furs"
,
378
),
new
new
Track
(
"Time Was"
,
451
));
Track shortestTrack
=
tracks
.
stream
()
.
min
(
Comparator
.
comparing
(
track
->
track
.
getLength
()))
.
get
();
assertEquals
(
tracks
.
get
(
1
),
shortestTrack
);
When we think about maximum and minimum elements, the first thing we need to think
about is the ordering that we're going to be using. When it comes to finding the shortest
track, the ordering is provided by the length of the tracks.
In order to inform the
Stream
that we're using the length of the track, we give it a
Compar-
ator
. Conveniently, Java 8 has added a static method called
comparing
that lets us build a
comparator using keys. Previously, we always encountered an ugly pattern in which we had
to write code that got a field out of both the objects being compared, then compare these
field values. Now, to get the same element out of both elements being compared, we just
provide a getter function for the value. In this case we'll use
length
, which is a getter func-
tion in disguise.
It's worth reflecting on the
comparing
method for a moment. This is actually a function that
takes a function and returns a function. Pretty meta, I know, but also incredibly useful. At
any point in the past, this method could have been added to the Java standard library, but the
poor readability and verbosity issues surrounding anonymous inner classes would have made
it impractical. Now, with lambda expressions, it's convenient and concise.
It's now possible for
max
to be called on an empty
Stream
so that it returns what's known as
an
Optional
value. An
Optional
value is a bit like an alien: it represents a value that may
exist, or may not. If our
Stream
is empty, then it won't exist; if it's not empty, then it will.
Let's not worry about the details of
Optional
for the moment, since we'll be discussing it in
get
method.