Return Optional as it is if the returned Optional has value, else call another function

adimoh :

I have two methods func1 and func2 which return Optional. Return Optional as it is if the returned Optional from func1 has value, else call func2 and return its Optional. One way is to use if-else.

Optional<MyObject> opt1 = func1();
if (opt1.isPresent()) {
    return opt1;
}
return func2();

However, I wish to achieve it using Java 8 Optional and avoid if-else.

Something like:

return Optional.of(obj1) 
        .flatMap_returnOptionalIfvaluePresent(func1)
        .orElseReturnOptionalFromThis(func2)

Can anyone suggest a good way for it?

Ole V.V. :

Edit: or

Java 9 and later offer a very elegant solution:

Optional<String> myFunc() {
    return func1().or(this::func2);
}

or (introduced in Java 9) does exactly what you asked for: If the Optional returned from func1 has a value, it is returned (or an equivalent Optional). If not, the supplier (here func2()) is invoked to get an Optional, which is then returned.

Java 8

There are several ways. In Java 8 I prefer to take the values out of the Optionals from func1 and func2:

Optional<String> myFunc() {
    String returnValue = func1().orElse(func2().orElse(null));
    return Optional.ofNullable(returnValue);
}

Edit 2: @Holger’s alternative suggestion in a comment is good enough for quoting within the answer (Holger, you may have posted it as a comment only because the question is closed and you therefore could not post your own answer):

    return func1().map(Optional::of).orElse(func2());

It goes the opposite way: The mapping using Optional::of wraps the Optional from func1 inside yet an Optional only if it has a value, from which orElse unwraps it again.

If the call to func2 is expensive, you may want to avoid it when it’s not needed (when func1 supplies a value):

    String returnValue = func1().orElseGet(() -> func2().orElse(null));

Or in Holger’s version:

    return func1().map(Optional::of).orElseGet(this::func2);

isPresent used in a couple of other answers is so low-level, I seldom use it and only as a last resort.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=69634&siteId=1