Chaining Optionals in Java 8

Photo Credit: http://www.birthinjuryjustice.org/chain-command/

Chaining Optionals in Java 8

Optionals in Java can help you to write a program without null checks. In addition they can make your code more concise and easier to read. Let’s look at an example how chaining Optionals in a Stream can help you avoid unnecessary null checks.

Motivation

The purpose of chaining Optionals in a Stream is to pick the first Optional which has a value and return it. You could have multiple service methods which return Optionals. Passing them to a Stream as method references allows you to process them lazily and return as soon as there’s something to return.

The following utility method takes Suppliers as arguments and returns the first Optional which has a value.

public static <T> Optional<T> first(Supplier<Optional<T>>... suppliers) {
    return Arrays.asList(suppliers).stream()
            .map(Supplier::get)
            .flatMap(o -> o.map(Stream::of).orElseGet(Stream::empty))
            .findFirst();
}

It is possible to use method references or lambda expressions as arguments.

first(this::find1, this::find2, this::find3);

Improvements in JDK9

JDK8 does not provide a convenient API for creating a Stream out of an Optional. Apparently this is going to be fixed in JDK9 and the utility method could be written as

public static <T> Optional<T> first(Supplier<Optional<T>>... suppliers) {
return Arrays.asList(suppliers).stream()
        .map(Supplier::get)
        .flatMap(Optional::stream)
        .findFirst();

Notice how the flatmap method has changed.

Food for thought

Think about how to implement the same concept without using Optionals or lambda expressions. It would probably include multiple null checks. Using a functional style can help you implement a more general solution which is hopefully easier to understand as well.

This blog post was inspired by a question and answers on StackOverflow.

comments powered by Disqus