Card 03/ 08
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.
| Method | When absent | The argument is evaluated |
|---|---|---|
orElse(value) | Returns the value you supplied | Always, even when present |
orElseGet(supplier) | Calls the supplier and returns what it gives | Only when absent |
orElseThrow(supplier) | Throws the exception the supplier builds | Only when absent |
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.
← → move through sections and cards