Java Joy: Optional orElse orElseGet That Is The Question
The Optional
class has the orElse
and orElseGet
methods to return a value when the Optional
object is empty. This is useful to return a default value for example. But there is a small difference between the two methods. The orElseGet
method needs a Supplier
argument that returns a value of the type of the Optional
value. The Supplier
is only invoked when the Optional
value is empty. The statement passed as argument to the orElse
method is always executed, even when the Optional
value is not empty. Preferrably we should use orElseGet
as it will only invoke statements if needed.
In the following example code we see when our method getDefaultGreeting
is invoked by using orElse
and orElseGet
with an empty and non-empty Optional
object:
package mrhaki.optional;
import java.util.Optional;
public class Sample {
/**
* Keep track of total number of times method getDefaultGreeting is invoked.
*/
private static int totalDefaultGreetingInvoked = 0;
public static void main(String[] args) {
// Define an empty optional.
var name = Optional.ofNullable(null);
// orElse returns value from argument when optional is empty.
assert ("Hello " + name.orElse(getDefaultGreeting())).equals("Hello world");
assert totalDefaultGreetingInvoked == 1;
// orElseGet needs a Supplier that is executed when the optional is empty.
assert ("Hello " + name.orElseGet(Sample::getDefaultGreeting)).equals("Hello world");
assert totalDefaultGreetingInvoked == 2;
// This time the optional is not empty.
name = Optional.ofNullable("mrhaki");
// orElse will always get the value, even when the optional is not empty.
assert ("Hello " + name.orElse(getDefaultGreeting())).equals("Hello mrhaki");
assert totalDefaultGreetingInvoked == 3;
// orElseGet will not call the Supplier when the optional is not empty.
assert ("Hello " + name.orElseGet(Sample::getDefaultGreeting)).equals("Hello mrhaki");
assert totalDefaultGreetingInvoked == 3;
}
private static String getDefaultGreeting() {
// Increase counter, so we can check the method is invoked.
totalDefaultGreetingInvoked++;
return "world";
}
}
Written with Java 15.