ComparisonDifficulty: Intermediate1 min

orElse vs orElseGet vs orElseThrow

Three ways out of an Optional, chosen by what should happen when it is empty.

orElse, orElseGet and orElseThrow each take the value out of an Optional. They differ in what happens when it is empty: a value you supply, a value computed only then, or an exception.

The three ways of unwrapping, and what each one costs
MethodWhen absentThe argument is evaluated
orElse(value)Returns the value you suppliedAlways, even when present
orElseGet(supplier)Calls the supplier and returns what it givesOnly when absent
orElseThrow(supplier)Throws the exception the supplier buildsOnly when absent
java
String a = found.orElse("unknown");
Customer b = found.orElseGet(() -> loadFromBackupStore(ref));
Customer c = found.orElseThrow(() -> new NoSuchCustomer(ref));

The decision rule. Use orElse for a cheap constant that is already in hand. Use orElseGet whenever producing the fallback costs anything at all: a database call, an allocation, a computation. Use orElseThrow when absence is a failure rather than a case to handle.

The third column is the one that matters most. An argument to orElse is computed before the call, like any argument; orElseGet and orElseThrow take a lambda, an inline function, and a lambda runs only when it is called.

Prefer map, filter and ifPresent to any of these three where they fit. Unwrapping is how you leave Optional, and staying inside it is usually shorter.