Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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; } 
like image 253
Feuermurmel Avatar asked Jul 06 '14 20:07

Feuermurmel


People also ask

How do you retrieve Optional value?

Retrieving the Value From Java 8 Optional Object Using get() Method. The get() method of Optional is simply used to return a value from the Optional object. Suppose the value is not present, then it throws the exception NoSuchElementException.

Why is null better than Optional?

In a nutshell, the Optional class includes methods to explicitly deal with the cases where a value is present or absent. However, the advantage compared to null references is that the Optional class forces you to think about the case when the value is not present.

How does orElse work with Optional?

Based on their Javadocs: orElse(): returns the value if present, otherwise returns other. orElseGet(): returns the value if present, otherwise invokes other and returns the result of its invocation.

What is isPresent in Optional?

Optional Class | isPresent() function The isPresent() function in Optional Class is used to evaluate whether the value if assigned to variable is present or not. Syntax value.isPresent() Returns: It returns true if value is assigned otherwise false.


2 Answers

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()); 
like image 114
aioobe Avatar answered Oct 22 '22 04:10

aioobe


EDIT: I totally thought you were using Guava's Optional originally. I've updated my answer to supply both Guava and Java 8 syntax for their respective Optional classes.

Java 8 Optional

You can shorten it up to this:

firstOptional.orElse(secondOptional.orElse(EMPTY_VALUE)) 

I'm not sure what you meant in your third bullet by "empty". If you meant null then this'll do the trick:

firstOptional.orElse(secondOptional.orElse(null)) 

orElse() is a method on Optional that will return the value if present, otherwise it will return the value you supplied as the argument to orElse().

Guava Optional

You can shorten it up to this:

firstOptional.or(secondOptional.or(EMPTY_VALUE)) 

I'm not sure what you meant in your third bullet by "empty". If you meant null then this'll do the trick:

firstOptional.or(secondOptional.orNull()) 

or() is a method on Optional that will return the value if present, otherwise it will return the value you supplied as the argument to or().

like image 26
Erik Gillespie Avatar answered Oct 22 '22 06:10

Erik Gillespie