When to use Optional.orElse() rather than Optional.orElseGet()

Viewed 4366

I've read the answers to this question about the difference between Optional.orElse() and Optional.orElseGet().

It seems that orElseGet() is always more efficient than orElse() because of lazy evaluation, and it's apparently visible even when benchmarking very simple examples like this one (see part 4): https://www.baeldung.com/java-optional-or-else-vs-or-else-get

So, are there any use cases where it's better to use orElse rather than orElseGet?

3 Answers
  1. In most cases, you type less when using orElse, since it is shorter than orElseGet and, compare the signatures of them:

orElse(T other)
orElseGet(Supplier<? extends T> other)

a Supplier<? extends T> other is most likely longer than T other. If the performance is not so critical you may choose to type less. Programmer's effort also counts :-) For example, compare:

orElseGet(() -> 1)
orElse(1)
  1. As your link has mentioned:

by default, it makes more sense to use orElseGet() every time unless the default object is already constructed and accessible directly.

One of the major use cases where it could be preferable would be when you know you need to fall back to a constant (or even an object already created) to default to. I mean, just compare how poor could this be :

int first = Stream.of(1,3,5).filter(i->i%2==0).findFirst().orElseGet(new Supplier<Integer>() {
    @Override
    public Integer get() {
        return 1;
    }
});

or its lambda representation

int first = Stream.of(1,3,5).filter(i->i%2==0).findFirst().orElseGet(() -> 1);

which is redundant as compared to

int first = Stream.of(1,3,5).filter(i->i%2==0).findFirst().orElse(1);

Below is the short answer, for a more detailed answer, please check out my stackoverflow answer here

  • orElse() will always call the given function whether you want it or not, regardless of Optional.isPresent() value
  • orElseGet() will only call the given function when the Optional.isPresent() == false

And as the first approach will always get the resource, you might want to consider the second approach when the required resource is expensive to get.

Related