Skip to content
PickNTech

Optional

Represent "maybe a value" explicitly and stop writing null checks everywhere.

Intermediate12 minUpdated 23 Sept 2026

What you’ll learn

  • Why Optional exists
  • map, filter and orElse
  • orElseThrow for required values
  • Where not to use Optional

The problem with null

String city = user.getAddress().getCity().toUpperCase();

If any of those return null, you get a NullPointerException. Worse, nothing in the method signatures warned you. Optional makes "this might be missing" part of the type.

Optional<User> findByEmail(String email);

Now every caller has to decide what happens when the user isn't found.

Creating an Optional

Optional.of(value);          // value must not be null
Optional.ofNullable(value);  // empty if value is null
Optional.empty();

Using an Optional

String city = repo.findByEmail(email)
        .map(User::address)
        .map(Address::city)
        .map(String::toUpperCase)
        .orElse("UNKNOWN");

Each map only runs if there's a value, so the chain safely short-circuits.

MethodDoes
map(fn)Transform the value if present
filter(pred)Keep the value only if it matches
orElse(x)Value, or a default
orElseGet(() -> x)Value, or a lazily computed default
orElseThrow()Value, or throw
ifPresent(fn)Run a side effect if present

orElseThrow for required values

In a Spring Boot service, a missing entity is usually an error:

public User getUser(long id) {
    return repo.findById(id)
            .orElseThrow(() -> new UserNotFoundException(id));
}

Don't do this

if (opt.isPresent()) return opt.get(); is just a null check with extra steps. Reach for map, orElse and orElseThrow instead.

Where not to use Optional

  • Fields — use a nullable field or a sensible default.
  • Method parameters — overload the method instead.
  • Collections — return an empty list, never Optional<List<T>>.

Optional was designed for return types.

QWhat's the difference between orElse and orElseGet?+

orElse(x) always evaluates x, even when the Optional has a value. orElseGet(supplier) only calls the supplier when the Optional is empty — use it when the default is expensive to compute.

Key takeaways

  • Use Optional as a return type for values that may be absent.
  • Chain map/filter and finish with orElse or orElseThrow.
  • Avoid isPresent() + get().

Finished this lesson?

Mark it complete to move forward on your roadmap.