Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 334
adimoh Avatar asked Jan 18 '19 09:01

adimoh


People also ask

What is return Optional?

The Optional type was introduced in Java 8. It provides a clear and explicit way to convey the message that there may not be a value, without using null. When getting an Optional return type, we're likely to check if the value is missing, leading to fewer NullPointerExceptions in the applications.

What does Optional empty () get () return?

Optional class in Java is used to get an empty instance of this Optional class. This instance do not contain any value. Parameters: This method accepts nothing. Return value: This method returns an empty instance of this Optional class.

How do you return Optional value?

To return the value of an optional, or a default value if the optional has no value, you can use orElse(other) . Note that I rewrote your code for finding the longest name: you can directly use max(comparator) with a comparator comparing the length of each String.

What is difference between isPresent and ifPresent?

isPresent() returns true if the given Optional object is non-empty. Otherwise it returns false. Optional. ifPresent() performs given action if the given Optional object is non-empty.

What is an optional function in C++ with example?

Virtual Member Functions C++ std::optional optional as return value Example std::optional<float> divide(float a, float b) { if (b!=0.f) return a/b; return {}; } Here we return either the fraction a/b, but if it is not defined (would be infinity) we instead return the empty optional.

When to use optional as a return type?

I also assume that Optional is only used as a return type when it's expected that there are cases where that method should have no value to return. Finally, these observations apply to other types and to direct use of null in Java as well, but Optional emphasizes and concretely illustrates these observations.

Can the return value of optional be null?

The returned Optional is a reference type and, like any reference type, can be null. It is paramount that a developer writing a method that returns Optional should NEVER have that method return null [ Optional.empty () should generally be returned instead]. I'm going to reiterate this point with two quotations:

How do I return the value of an optional in Java?

To return the value of an optional, or a default value if the optional has no value, you can use orElse(other). public String longestName() { Optional<String> longNameOpt = someList.stream().max(Comparator.comparingInt(String::length)); return longNameOpt.orElse("not present"); }.


2 Answers

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.

like image 198
Ole V.V. Avatar answered Nov 01 '22 15:11

Ole V.V.


If you're using java 9+, you can just use Optional.or:

return func1().or(() -> func2());

In Java 8, you may need to create a new Optional from results (use orElseGet to avoid eager execution):

return Optional.ofNullable(func1().orElseGet(() -> func2().orElse(null)));
like image 28
ernest_k Avatar answered Nov 01 '22 14:11

ernest_k