Get value from one Optional or another

Feuermurmel picture Feuermurmel · Jul 6, 2014 · Viewed 27.8k times · Source

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;
}

Answer

aioobe picture aioobe · Jul 6, 2014

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());