4.3.  Use the Optional class


A java.util.Optional<T> object is either a wrapper for an Object of type T or a wrapper for no object. It is intended as a safer alternative than a reference of type T that refers to an Object or null.

Following is the declaration for java.util.Optional<T> class:

public final class Optional<T> extends Object {


Creating Optional objects

The first step before working with Optional is to learn how to create optional objects. There are several ways:

Unwrapping an Optional

The Optional class provides several instance methods to read the value contained by an Optional instance.

Converting an Optional into a Stream

The Optional.stream() method allows you to convert an Optional to a Stream.

If the Optional contains a value, it will return a Stream containing only that value, otherwise, it will return an empty Stream:

Optional<Integer> in = Optional.of(1);
    .filter(i -> i > 0)



The Optional.stream() method can be helpful when you are dealing with a stream of Optional elements. It will help to filter out empty optionals and keep the ones with values.

Assume we have a list of optionals received from a method, and some of the optionals are empty:

Stream<Optional<String>> stream = Stream.of(


In Java 8.0 you could remove empty optionals as follows:

List<String> list = stream
    .flatMap(o -> o.isPresent() ? Stream.of(o.get()) : Stream.empty())


In Java 9.0 and later you can remove empty optionals with shorter code using flatMap():

List<String> list = stream 


The map() and flatMap() in Optional


Both Optional.map() and Optional.flatMap() return an Optional.

Use Optional.map() if the function returns the object you need; or Optional.flatMap() if the function returns an Optional.

If the function returns the exact type we need:

Optional<String> s = Optional.of("Java");
s = s.map(String::toUpperCase); // function returns String


If we have a function that returns an Optional then using map() would lead to a nested structure of optionals, as the map() does an additional wrapping. Use flatMap() to keep a flat structure:

Optional<String> s = Optional.of("Java");
s = s.flatMap(val -> Optional.of(val.toUpperCase())); // function returns Optional<String>


Professional hosting         Exam 1Z0-817: Upgrade OCP Java 6, 7 & 8 to Java SE 11 Developer Quiz     Exam 1Z0-810: Upgrade to Java SE 8 Programmer Quiz