The new Java 8 stream framework and friends make for some very concise java code, but I have come across a seemingly-simple situation that is tricky to do concisely.
Consider a List<Thing> things
and method Optional<Other> resolve(Thing thing)
. I want to map the Thing
s to Optional<Other>
s and get the first Other
. The obvious solution would be to use things.stream().flatMap(this::resolve).findFirst()
, but flatMap
requires that you return a stream, and Optional
doesn't have a stream()
method (or is it a Collection
or provide a method to convert it to or view it as a Collection
).
The best I can come up with is this:
things.stream()
.map(this::resolve)
.filter(Optional::isPresent)
.map(Optional::get)
.findFirst();
But that seems awfully long-winded for what seems like a very common case. Anyone have a better idea?
Best Answer
Java 9
Optional.stream
has been added to JDK 9. This enables you to do the following, without the need of any helper method:Java 8
Yes, this was a small hole in the API, in that it's somewhat inconvenient to turn an
Optional<T>
into a zero-or-one lengthStream<T>
. You could do this:Having the ternary operator inside the
flatMap
is a bit cumbersome, though, so it might be better to write a little helper function to do this:Here, I've inlined the call to
resolve()
instead of having a separatemap()
operation, but this is a matter of taste.