Java

Chapter 87: Optional in Java — Explicit Absence, map flatMap, and Avoiding Optional Fields

Learn java.util.Optional: empty vs of, map flatMap chain, orElse vs orElseGet, orElseThrow, stream findFirst, and why Optional member fields are usually discouraged.

Author: Sushil Kumar

Java OptionalJava Optional map flatMapJava orElse orElseGetJava Optional best practicesJava null safety Optional

Chapter 87: Optional in Java

Optional<T> wraps zero or one value. It does not remove null from the language—it gives you a typed box so callers remember to branch instead of dereferencing blindly.

reduce (Chapter 86) already returned Optional for empty folds. Here the focus is API design and composition.


1. Topic title

Optional: “maybe there is a T”—compose with map instead of nested null checks


2. What it means

  • Optional.of(x)x must not be null or NullPointerException throws immediately.
  • Optional.ofNullable(x)empty if x is null, otherwise of.
  • map — if present, transform value; if empty, stay empty.
  • flatMap — when your mapper already returns Optional—avoids Optional<Optional<...>>.

orElse evaluates the fallback always; orElseGet takes a Supplier and runs only when empty.


3. Why it is used

Return types for searches (findUserById), stream terminators (findFirst), pipeline stages that might legitimately find nothing—self-documenting intent.


4. Mental sketch

Optional is a gift box that might be empty. map decorates the gift inside; if the box was empty, you still hold an empty box, not null chaos.


5. Java code example

import java.util.Optional;
 
public class OptionalDemo {
    static Optional<String> nick(String raw) {
        if (raw == null || raw.isBlank()) {
            return Optional.empty();
        }
        return Optional.of(raw.trim());
    }
 
    public static void main(String[] args) {
        String out =
                nick("  ada  ")
                        .map(String::toUpperCase)
                        .filter(s -> s.length() <= 6)
                        .orElseGet(() -> "guest");
        System.out.println(out);
 
        try {
            nick(null).orElseThrow(() -> new IllegalStateException("missing nick"));
        } catch (IllegalStateException ex) {
            System.out.println("threw as expected: " + ex.getMessage());
        }
    }
}

filter on Optional keeps the value only if the predicate passes—similar spirit to Stream.filter.


6. Explanation of code

orElseThrow ends the chain with an exception when empty—good for “must exist” invariants after other validation.


7. Common mistakes

Using Optional fields on entities—serialization noise, memory, awkward equals. Prefer Optional return types at method boundaries.

Returning null Optional—do not; return Optional.empty().


8. Best practices

Do not get() without isPresent unless you immediately orElse / orElseThrow—same danger as null.

Prefer ifPresentOrElse (Java 9+) when you need both branches cleanly.


9. Small practice task

Parse an Integer with Optional.ofNullable(str).map(Integer::parseInt)—catch NumberFormatException by switching to flatMap with a try/catch helper returning Optional.empty() on bad input (small safeParse method).


Beginner tip

Optional is not a silver null killer—if everything becomes Optional, you traded null for box juggling. Use it at edges: parsers, repositories, stream finds.