In the previous post in this series, we examined features of the Stream API added in Java 9. A very useful API that plays well with streams, and was, in fact, used to make streams more robust, is Optional. Let’s explore it with JShell!

Optional provides a container that may or may not contain a non-null value. It was introduced in Java 8 to reduce the number of places in the code where a NullPointerException can be generated.

Its basic API is pretty simple. We can create an empty Optional:

Or an Optional containing something:

We can check if a value is present:

We could also call any other method of the relatively simple API that Optional exposes:

JDK 9 added 3 of these methods, ifPresentOrElse, or, and stream, which help us deal with default values, in a way.

1. ifPresentOrElse

Since Java 8, Optional has provided a method called ifPresent. This method checks if there is a value in the given Optional, and if it’s found, it performs an action on this value. Otherwise, the method does nothing. For example:

Java 9 introduces ifPresentOrElse. The method behaves like ifPresent, but it allows us to specify a default action to perform if no value is present in our Optional. For example:

This is useful when we want to perform a specific action on the value, but track when the action couldn’t be performed, for example by firing an event, logging a message, or updating a metric.

2. or

The or method checks if the given Optional contains a value. If a value is present, it returns an Optional describing the value (the same Optional). If no value is present, a new Optional generated by the supplying function is returned.

The method is similar to 2 other methods we know from Java 8 - orElse and orElseGet.

orElse returns the value in the given Optional if a value is present. Otherwise, a default value provided by the caller is returned. For example:

Like orElse, orElseGet returns the value in the Optional if a value is present. Unlike orElse, however, orElseGet allows us to specify a supplying function returning a default value if there’s no value in the Optional. For instance:

What orElse and orElseGet have in common is that they return values from inside an Optional, not the Optional itself. That’s what the new or method is for:

Although it might not be immediately obvious, this method is very useful for providing a fluent way of chaining operations on Optionals without having to shuffle between the containers and the values they wrap.

3. stream

Another useful addition to the API is the method stream. If a value is present in the given Optional, the method returns a stream containing only that value. An empty stream is returned otherwise. For instance:

In a way, the stream method is similar to the ofNullable method on streams. It’s extremely useful if we want to take advantage of the lazy nature of streams – compare e.g. the eager behaviour of the map method on Optionals to the lazy behaviour of the map method on streams. The method is also useful when operating on streams of Optionals. For example, it’s particularly suited for a mapper passed to the flatMap method on streams when a stream of Optionals needs to be processed.

Overall, the additions to Optional in Java 9 might seem minor, but they allow us to write cleaner code, which is very exciting. Try them out!