Search code examples
javajava-streamoption-type

findFirst on a Stream<Optional<T>>


Say you've got a stream of Optional<T>, that you want to fire a Consumer<T> on (if present).

What's the most elegant way of handling this?

I can manage by filtering by Optional::isPresent and mapping by Optional::isGet, but that seems "hacky" and not in the spirit of Optional:

Stream.of(a, b, c, d)
   .filter(Optional::isPresent)
   .map(Optional::get)
   .findFirst()
   .ifPresent(s -> System.out.println("This was cumbersome: " + s));

Solution

  • I agree that it's cumbersome but it's probably about the most straightforward solution without getting even more hacky.

    One thing I've done in a similar situation is to create a method to turn an Optional into a Stream:

    private Stream<T> optionalStream(Optional<T> optional) {
        if (optional.isPresent())
            return Stream.of(optional.get());
        else
            return Stream.empty());
    }
    

    So you can then use flatMap:

    Stream.of(a, b, c, d)
        .flatMap(this::optionalStream).findFirst()...
    

    From Java 9 the Stream method has been added to Optional to do exactly this so you can use:

    Stream.of(a, b, c, d)
        .flatMap(Optional::stream)
        .findFirst()...
    

    But to be honest I'm not sure this is all that much simpler than your filter then map solution.