Optional
null has been called the billion-dollar mistake: any reference might secretly be absent, and forgetting to check causes NullPointerExceptions. Optional is a container that makes "there might be no value" explicit in a method's return type, and offers safe ways to deal with the empty case.
Creating Optionals
JAVA
import java.util.Optional; public class Main { public static void main(String[] args) { Optional<String> some = Optional.of("Ana"); Optional<String> none = Optional.empty(); String maybeNull = null; Optional<String> fromNullable = Optional.ofNullable(maybeNull); System.out.println(some); System.out.println(none); System.out.println(some.isPresent() + " " + none.isEmpty() + " " + fromNullable.isEmpty()); } }
Output
Optional[Ana] Optional.empty true true true
Returning Optional from a method
JAVA
import java.util.List; import java.util.Optional; record Customer(int id, String name, String email) {} public class Main { static final List<Customer> CUSTOMERS = List.of(new Customer(1, "Ana", "ana@example.com"), new Customer(2, "Julia", null)); static Optional<Customer> findById(int id) { return CUSTOMERS.stream().filter(c -> c.id() == id).findFirst(); } public static void main(String[] args) { System.out.println(findById(1).map(Customer::name).orElse("unknown")); System.out.println(findById(9).map(Customer::name).orElse("unknown")); } }
Output
Ana unknown
The return type Optional<Customer> tells every caller "this can come back empty" — they can't forget, because they must unwrap it.
Getting the value out
JAVA
import java.util.Optional; public class Main { public static void main(String[] args) { Optional<String> city = Optional.empty(); System.out.println(city.orElse("Lisbon")); System.out.println(city.orElseGet(() -> "computed default")); city.ifPresentOrElse(c -> System.out.println("City: " + c), () -> System.out.println("No city")); try { city.orElseThrow(() -> new IllegalStateException("City required")); } catch (IllegalStateException e) { System.out.println(e.getMessage()); } } }
Output
Lisbon computed default No city City required
| Method | When empty |
|---|---|
orElse(value) | Returns the default (always evaluated) |
orElseGet(supplier) | Calls the supplier — use when the default is costly |
orElseThrow() | Throws NoSuchElementException (or your exception) |
ifPresent(action), ifPresentOrElse | Runs code only if a value is present |
get() | Throws — avoid; it defeats the purpose |
Transforming: map, filter, flatMap
JAVA
import java.util.Optional; record Customer(String name, String email) {} public class Main { static Optional<String> domainOf(Optional<Customer> customer) { return customer .map(Customer::email) .filter(e -> e.contains("@")) .map(e -> e.substring(e.indexOf('@') + 1)); } public static void main(String[] args) { System.out.println(domainOf(Optional.of(new Customer("Ana", "ana@example.com")))); System.out.println(domainOf(Optional.of(new Customer("Julia", null)))); System.out.println(domainOf(Optional.empty())); } }
Output
Optional[example.com] Optional.empty Optional.empty
map transforms the value if present; if the function returns null, the result becomes empty. A chain of operations stays safe without a single if (x != null).
Guidelines
- Use
Optionalas a return type for "may not find a result" methods. - Don't use it for fields, method parameters or collection elements — that adds clutter without much benefit.
- Never return
nullfrom a method declared to returnOptional. - For collections, return an empty collection rather than
Optional<List>ornull. OptionalInt,OptionalDoubleandOptionalLongavoid boxing.
Try it yourself
Look up a product's discount in a map, defaulting to zero, and apply it.
Output
mug: 10% off throw: 0% off lamp: 25% off