6
What is the difference between the methods orElse()
and orElseGet()
, class java.util.Optional
?
6
What is the difference between the methods orElse()
and orElseGet()
, class java.util.Optional
?
6
Both return something if the Optional
has no value.
The difference is in the orElse
you provide the value to be returned, and orElseGet
you provide a Supplier
(an object that returns the value). Ex:
Optional<String> opt = Optional.empty();
System.out.println(opt.orElse("ola"));
System.out.println(opt.orElseGet(() -> "ola"));
Both print "ola"
. Of course within the orElseGet
you can create a method as complex as you want:
System.out.println(opt.orElseGet(() -> {
// faz outras coisas complexas aqui
return resultadoDasCoisasComplexasAcima;
}));
But nothing prevents the method that does various complex things from being called directly and the result passed to orElse
:
System.out.println(opt.orElse(metodoQueFazVariasCoisasComplexas()));
The difference is that in this case the method is called and its return is passed to orElse
. Already if I call orElseGet
, the method is only called if the Optional
has no value:
public String metodo() {
System.out.println("dentro do método");
return "ola";
}
...
Optional<String> opt = Optional.empty();
System.out.println(opt.orElse(metodo()));
System.out.println(opt.orElseGet(() -> metodo()));
Like the Optional
is empty, both will call by the method. The output is:
dentro do método
ola
dentro do método
ola
But if the Optional
is not empty:
Optional<String> opt = Optional.of("teste");
System.out.println(opt.orElse(metodo()));
System.out.println(opt.orElseGet(() -> metodo()));
The method is only called in the first case, because the return of it must be passed to orElse
. Already the orElseGet
only calls the method if the Optional
is empty (then in this case it is not called). The output is:
dentro do método
teste
teste
This makes a difference in cases where the method to be called is very expensive (it makes complex, time-consuming operations, spends a lot of processing or memory, the returned object is "very large", etc.). In such cases, use orElseGet
is a better option than orElse
, because then the method is only called when really necessary.
And as quoted in the comments, there is still the method orElseThrow
, who receives a Supplier
which creates an exception. In this case, the exception is cast if the Optional
be empty:
Optional<String> opt = Optional.empty();
String valor = opt.orElseThrow(IllegalArgumentException::new);
In the code above, as the Optional
is empty, a IllegalArgumentException
.
Browser other questions tagged java java-8
You are not signed in. Login or sign up in order to post.
I would put the real need case: when the default value is weighed to be generated. But how (apart from this detail) your answer would be the same as I would put, is the suggestion of improvement =)
– Jefferson Quesado
Perhaps you could put as a curiosity the question of
orElseThrow
– Jefferson Quesado
@Jeffersonquesado Updated reply, thanks for the suggestions!
– hkotsubo