Optional<T>: a container for absent values
Expressing "might be empty" without null — and the get() trap.
Optional is a single-element box that might be empty
Optional<T> wraps a value that might not exist, making the possibility of absence explicit in the type rather than hidden in a null convention.
Creating Optionals:
Optional<String> present = Optional.of("Ada"); // value must be non-null
Optional<String> maybe = Optional.ofNullable(name); // null → empty
Optional<String> empty = Optional.empty();
Querying:
if (opt.isPresent()) { String s = opt.get(); } // classic — but verbose
opt.ifPresent(System.out::println); // cleaner: callback if present
Extracting with a fallback:
String val1 = opt.orElse("default"); // always evaluates the arg
String val2 = opt.orElseGet(() -> compute()); // lazy: only calls if empty
String val3 = opt.orElseThrow(); // throws if empty
Transforming:
Optional<Integer> length = opt.map(String::length); // still Optional
Optional<String> upper = opt.filter(s -> s.length() > 3)
.map(String::toUpperCase);
map on an empty Optional returns empty — the chain short-circuits safely. flatMap is for when the mapping function itself returns an Optional (avoids Optional<Optional<T>>).