Java Optional

Optional (Java 8) is a box which may or may not have a value. A method returns an Optional to say clearly: “the result can be missing”. It helps you to avoid the NullPointerException.

Create an Optional

import java.util.Optional;

public class Main {
    public static void main(String[] args) {
        Optional<String> a = Optional.of("Java");           // a value (never null)
        Optional<String> b = Optional.empty();              // no value
        Optional<String> c = Optional.ofNullable(null);     // value or empty

        System.out.println(a);
        System.out.println(b);
        System.out.println(c.isPresent());
        System.out.println(a.get());
    }
}
Output

Optional[Java]
Optional.empty
false
Java

Use the value safely

import java.util.Optional;

public class Use {
    static Optional<String> findCity(String user) {
        return user.equals("riya") ? Optional.of("Delhi") : Optional.empty();
    }

    public static void main(String[] args) {
        Optional<String> city = findCity("riya");
        city.ifPresent(c -> System.out.println("City: " + c));

        String other = findCity("aman").orElse("Unknown");
        System.out.println(other);

        String upper = findCity("riya").map(String::toUpperCase).orElse("none");
        System.out.println(upper);

        findCity("aman").ifPresentOrElse(
                c -> System.out.println("Found " + c),
                () -> System.out.println("No city for aman"));

        System.out.println(findCity("aman").or(() -> Optional.of("Default")).get());
    }
}
Output

City: Delhi
Unknown
DELHI
No city for aman
Default

get() on an empty Optional

Calling get() on an empty Optional throws NoSuchElementException. Prefer orElse, orElseGet or orElseThrow:

import java.util.Optional;

public class Throw {
    public static void main(String[] args) {
        Optional<String> empty = Optional.empty();
        try {
            empty.get();
        } catch (java.util.NoSuchElementException e) {
            System.out.println("get() failed: " + e.getMessage());
        }
        try {
            empty.orElseThrow(() -> new IllegalStateException("User not found"));
        } catch (IllegalStateException e) {
            System.out.println(e.getMessage());
        }
    }
}
Output

get() failed: No value present
User not found

Optional in streams

import java.util.List;

public class Stream {
    public static void main(String[] args) {
        List<Integer> numbers = List.of(4, 8, 15);
        System.out.println(numbers.stream().filter(n -> n > 10).findFirst());
        System.out.println(numbers.stream().filter(n -> n > 100).findFirst());
        System.out.println(numbers.stream().max(Integer::compare).get());
    }
}
Output

Optional[15]
Optional.empty
15

Good practice

  • Use Optional as a return type of a method.
  • Do not use it for fields, parameters or in collections.
  • Never return null when the return type is Optional.
  • orElse(x) always makes x. Use orElseGet(() -> ...) when it is costly to make.
Note: The best fight against null is to design the code so that missing values are rare and clear. Next: Java Date and Time.

Congratulations! Chapter Finished. Learn more about the similar topics:
Exercises & Assignments
No Content Found.
Interview Questions & Answers
No Content Found.