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.
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);
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")));