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

jbx picture jbx · Oct 16, 2015 · Viewed 128.4k times · Source

I am trying to understand the difference between the Optional<T>.orElse() and Optional<T>.orElseGet() methods.

The description for the orElse() method is "Return the value if present, otherwise return other."

While, the description for the orElseGet() method is "Return the value if present, otherwise invoke other and return the result of that invocation."

The orElseGet() method takes a Supplier functional interface, which essentially does not take any parameters and returns T.

In which situation would you need to use orElseGet()? If you have a method T myDefault() why wouldn't you just do optional.orElse(myDefault()) rather than optional.orElseGet(() -> myDefault()) ?

It does not seem that orElseGet() is postponing the execution of the lambda expression to some later time or something, so what's the point of it? (I would have thought that it would be more useful if it returned a safer Optional<T> whose get() never throws a NoSuchElementException and isPresent() always returns true... but evidently its not, it just returns T like orElse()).

Is there some other difference I am missing?

Answer

biziclop picture biziclop · Oct 16, 2015

Take these two scenarios:

Optional<Foo> opt = ...
Foo x = opt.orElse( new Foo() );
Foo y = opt.orElseGet( Foo::new );

If opt doesn't contain a value, the two are indeed equivalent. But if opt does contain a value, how many Foo objects will be created?

P.s.: of course in this example the difference probably wouldn't be measurable, but if you have to obtain your default value from a remote web service for example, or from a database, it suddenly becomes very important.