Search code examples
javajava-8option-type

Get value from one Optional or another


I have two java.util.Optional instances and I want to get an Optional that either:

  • Has the value of the first Optional, if it has a value.
  • Has the value of the second Optional, if it has a value.
  • Is empty of neither Optional has a value.

Is there a straight-forward way to do that, i.e. is there already some API to do that?

The following expressions will do that, but I have to mention the first optional twice:

firstOptional.isPresent() ? firstOptional : secondOptional

This is exactly what com.google.common.base.Optional.or() does, but that method is not present in Java 8's API.


The accepted answer by aioobe lists a few alternative approaches to overcome this omission of the Optional API right where such a value has to be computed (which answers my question). I've now opted to add a utility function to my codebase:

public static <T> Optional<T> or(Optional<T> a, Optional<T> b) {
    if (a.isPresent())
        return a;
    else
        return b;
}

Solution

  • Java 9 and above:

    firstOptional.or(() -> secondOptional);
    

    Java 8 and below

    If you want to avoid mentioning firstOptional twice, you'd probably have to go with something like

    firstOptional.map(Optional::of).orElse(secondOptional);
    

    or

    Optional.ofNullable(firstOptional.orElse(secondOptional.orElse(null)));
    

    But the most readable variant is probably to simply do

    Optional<...> opt = firstOptional.isPresent()  ? firstOptional
                      : secondOptional.isPresent() ? secondOptional
                      : Optional.empty();
    

    If someone stumbles across this question but has a list of optionals, I'd suggest something like

    Optional<...> opt = optionals.stream()
                                 .filter(Optional::isPresent)
                                 .findFirst()
                                 .orElse(Optional.empty());