Mastery
Mastery/Java/D. Streams & functional interfaces
T1 · high-leverage

Optional: orElse (always evaluated) vs orElseGet (lazy)

orElse(x) takes an already-evaluated value as a plain method argument -- Java has to compute x before calling orElse, regardless of whether the Optional is present. orElseGet(supplier) only invokes the supplier if the Optional is actually empty. This matters whenever the fallback is expensive (a DB call, a network request) -- orElse pays that cost every time, even when it throws the result away.

java
import java.util.*;

String compute(String tag) {
    System.out.println("  (compute(" + tag + ") actually called)");
    return "computed-" + tag;
}

Optional<String> present = Optional.of("value");

System.out.println("present.orElse(compute(A)):");
String r1 = present.orElse(compute("A"));   // compute("A") runs regardless -- wasted work
System.out.println("  result: " + r1);

System.out.println("present.orElseGet(-> compute(B)):");
String r2 = present.orElseGet(() -> compute("B"));   // supplier never runs, Optional was present
System.out.println("  result: " + r2);
java
Optional<String> empty = Optional.empty();
System.out.println("for an EMPTY Optional, both trigger the fallback:");
System.out.println("empty.orElse(compute(C)): " + empty.orElse(compute("C")));
System.out.println("empty.orElseGet(-> compute(D)): " + empty.orElseGet(() -> compute("D")));

Interview angle

A precise, high-signal question: "what's the difference between orElse and orElseGet, and when does it actually matter?" Candidates who've only skimmed Optional's API often say "they're the same" — the correct answer requires understanding that orElse's argument is a plain method parameter, evaluated eagerly no matter what, which is exactly the kind of detail that only shows up once you've profiled or debugged a surprising extra database call.

In the industry

This is a real, recurring performance bug: optional.orElse(expensiveFallbackCall()) silently pays the cost of the fallback on every call, present or not. Static analysis tools (like Error Prone's OptionalOrElseCall) which flag exactly this pattern for anything more expensive than a constant. It's also why Optional as a field type is broadly considered an anti-pattern — Optional was designed as a return type for "might not have a value," not as a general-purpose nullable wrapper for object state.