Optional in Java 8 cheat sheet

java.util.Optional<T> in Java 8 is a poor cousin of scala.Option[T] and Data.Maybe in Haskell. But this doesn’t mean it’s not useful. If this concept is new to you, imagine Optional as a container that may or may not contain some value. Just like all references in Java can point to some object or be null, Option may enclose some (non-null!) reference or be empty.

aridalsvannet

Turns out that the analogy between Optional and nullable references is quite sensible. Optional was introduced in Java 8 so obviously it is not used throughout the standard Java library – and never will be for the backward compatibility reasons. But I recommend you at least giving it a try and using it whenever you have nullable references.Optional instead of plain null is statically checked at compile time and much more informative as it clearly indicates that a given variable may be present or not. Of course it requires some discipline – you should never assign null to any variable any more.

Usage of option (maybe) pattern is quite controversial and I am not going to step into this discussion. Instead I present you with few use-cases of null and how they can be retrofitted to Optional<T>. In the following examples given variables and types are used:

In the first case Optionalmust contain not null value and will throw an exception if null is passed. ofNullable() will either return empty or present (set) Optional. empty( always return empty Optional, corresponding to null. It’s a singleton because Optional<T> is immutable.

This becomes tricky. Optional.map() applies given function on a value inside Optional – but only if Optional is present. Otherwise nothing happens and empty() is returned. Remember that the transformation is type-safe – look at generics here:

flatMap() – we need to go deeper

Imagine you have a function that does not accept null but may produce one:

public String findSimilar(@NotNull String s) //...

Using it is a bit cumbersome:

String similarOrNull = x != null? findSimilar(x) : null;

With Optional it is a bit more straighforward:

Optional<String> similar = opt.map(this::findSimilar);

If the function we map() over returns null, the result of map() is an empty Optional. Otherwise it’s the result of said function wrapped with (present) Optional. So far so good but why do we return null-able value if we have Optional?

public Optional<String> tryFindSimilar(String s) //...

Our intentions are clear but using map() fails to produce correct type. Instead we must use flatMap():

Do you see double Optional<Optional<...>>? Definitely not what we want. If you are mapping over a function that returns Optional, use flatMap instead. Here is a simplified implementation of this function:

Is it more readable? Hard to tell. But at least it’s impossible to produce NullPointerException when Optional is used consistently.

Converting Optional<T> to List<T>

I sometimes like to think about Optional as a collection 1 having either 0 or 1 elements. This may make understanding of map() and flatMap() easier. Unfortunately Optional doesn’t have toList() method, but it’s easy to implement one:

But why limit ourselves to List<T>? What about Set<T> and other collections? Java 8 already abstracts creating arbitrary collection via Collectors API, introduced for Streams. The API is hideous but comprehensible:

Summary

Optional<T> is not nearly as powerful as Option[T] in Scala (but at least it doesn’t allow wrapping null). The API is not as straightforward as null-handling and probably much slower. But the benefit of compile-time checking plus readability and documentation value of Optional used consistently greatly outperforms disadvantages. Also it will probably replace nearly identical com.google.common.base.Optional<T> from Guava

1 – from theoretical point of view both maybe and sequence abstractions are monads, that’s why they share some functionality

Newsletter

Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

Email address:

Recent Jobs

No job listings found.

Join Us

With 1,240,600 monthly unique visitors and over 500 authors we are placed among the top Java related sites around. Constantly being on the lookout for partners; we encourage you to join us. So If you have a blog with unique and interesting content then you should check out our JCG partners program. You can also be a guest writer for Java Code Geeks and hone your writing skills!

Disclaimer

All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners. Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries. Examples Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.