java.util.Optional

What is Optional?

Optional<T> is a container object introduced in Java 8 to represent a value that may or may not be present, helping to avoid NullPointerException.
Instead of returning null, methods can return an Optional to indicate "value present" or "value absent".

Creating an Optional

import java.util.Optional;

public class OptionalExample {
  public static void main(String[] args) {
    // Empty Optional
    Optional<String> emptyOpt = Optional.empty();

    // Optional with non-null value
    Optional<String> nameOpt = Optional.of("Alice");

    // Optional that can hold null (safe creation)
    Optional<String> nullableOpt = Optional.ofNullable(null);

    System.out.println(emptyOpt.isPresent()); // false
    System.out.println(nameOpt.isPresent()); // true
  }
}

Key methods:

  • Optional.empty() → No value
  • Optional.of(value) → Value must be non-null
  • Optional.ofNullable(value) → Accepts null

Accessing Values Safely

Optional<String> opt = Optional.of("Hello");

// 1. isPresent() / get()
if (opt.isPresent()) {
  System.out.println(opt.get()); // "Hello"
}

// 2. ifPresent()
opt.ifPresent(val -> System.out.println(val.toUpperCase()));

// 3. orElse / orElseGet / orElseThrow
String result1 = opt.orElse("Default");
String result2 = opt.orElseGet(() -> "Generated Default");
String result3 = opt.orElseThrow(() -> new IllegalArgumentException("No value"));

Best practice: Avoid isPresent() + get() together; prefer ifPresent or orElse.

Transforming Values

Optional<String> nameOpt = Optional.of("Bob");

// map() transforms the value if present
Optional<Integer> lengthOpt = nameOpt.map(String::length);
System.out.println(lengthOpt.orElse(0)); // 3

// flatMap() when the mapper returns another Optional
Optional<String> upperOpt = nameOpt.flatMap(n -> Optional.of(n.toUpperCase()));
System.out.println(upperOpt.get()); // "BOB"

Filtering Values

Optional<String> nameOpt = Optional.of("Charlie");

nameOpt
  .filter(name -> name.startsWith("C"))
  .ifPresent(System.out::println); // "Charlie"

nameOpt
  .filter(name -> name.startsWith("Z"))
  .ifPresent(System.out::println); // No output

Common Use Case: Avoiding Null Checks

public Optional<String> findUserEmail(String username) {
  if ("admin".equals(username)) {
    return Optional.of("admin@example.com");
  }
  return Optional.empty();
}

public static void main(String[] args) {
  OptionalExample ex = new OptionalExample();
  String email = ex.findUserEmail("guest")
           .orElse("no-reply@example.com");
  System.out.println(email); // "no-reply@example.com"
}


 Best Practices

✅ Use Optional as a return type, not for fields or parameters.
✅ Prefer orElseGet() over orElse() when the default value is expensive to compute.
✅ Avoid Optional.get() without checking presence.
✅ Chain mapfilter, and flatMap for cleaner code.
← Back to Learning Journey