Java Optional working of orElse is not as if else

Use orElseGet() to avoid evaluating getDefaultPoJo() when the Optional is not empty:

PoJo poJo1=getNullPoJo().orElseGet(() -> getDefaultPoJo());
PoJo poJo2=getLoadedPoJo().orElseGet(() -> getDefaultPoJo());

getNullPoJo().orElse(getDefaultPoJo());

It's a method chain, and every method in this chain will get executed, no matter how the underlying API is supposed to work.

1) getNullPoJo()
2) r = getDefaultPoJo()
3) orElse(r)  

In order to execute a method, its actual parameters must be evaluated. To call orElse(getDefaultPoJo()), getDefaultPoJo() must be invoked as well. That's the reason you are getting more than you expected.

Usually, you will see

.orElse(null);
.orElse(defaultValue);

where null, and defaultValue are predefined values that don't require any calculations.

On the other hand, we write

.orElseGet(() -> generateDefaultValue());
.orElseGet(() -> calculateDefaultOutcome());

where generateDefaultValue and calculateDefaultOutcome are methods that do perform some calculations (intensive ones or ones we don't want to execute until the right moment [your case]).

Compare,

.orElseGet(() -> createDefaultPoJo());
.orElse(DEFAULT_POJO);

where DEFAULT_POJO is a variable initialised prior to this method call, and createDefaultPoJo() is a method that creates a default instance every time it gets called.


The output is correct, Optional.orElse() will allways execute the else-action. (the expression you provide) Use orElseGet() -which only calls the function if Optional.isPresent == false- for your desired output:

Difference between `Optional.orElse()` and `Optional.orElseGet()`

https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html#orElseGet-java.util.function.Supplier-

Tags:

Java