paint-brush
Java Optional is Complicatedby@anicolaspp
1,774 reads
1,774 reads

Java Optional is Complicated

by Nicolas A PerezFebruary 24th, 2018
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

For long, long time, I have not written code in <em>Java</em> since if there is a need for the JVM then <em>Scala</em> is my way to go. However, that changes from time to time, specially when I have to work on a <em>Java</em> shop.

Companies Mentioned

Mention Thumbnail
Mention Thumbnail
featured image - Java Optional is Complicated
Nicolas A Perez HackerNoon profile picture

For long, long time, I have not written code in Java since if there is a need for the JVM then Scala is my way to go. However, that changes from time to time, specially when I have to work on a Java shop.

With the new advances on the Java language, I would say Java is way easier to work with compare to few years back. There is a lot of movement towards functional programming and it can be seen in the recent additions in the newest versions of Java.

After a lot of efforts to incorporate all these features, there are few that still are a little incompleted.

Let’s look at Optional and how to work with it and also how it compares to the Scala.Option.

The main idea behind Optional is to avoid nulls and to avoid NullPointerException. However, it feels the one we found in Java actually promotes the use of nulls. Let’s see how.

This will throw NullPointerException every time we send a null to it. Instead, we need to use .ofNullable method.

Isn’t the main idea to avoid these exceptions? Then why do we get two ways that work so differently from each other and have so different results.

In Scala, we only have to do:

Note that I am keeping the types at the highest level so everyone could actually be nullable.

The point is Option.apply(somethingNull),which is the same as Option(somethingNull), will take care of the null and create the appropriate result for us without throwing NullPointerException which is the exact problem we want to avoid.

For our own sake, Java Optional has the right .map and .flatMap and they work as they do in Scala or any other language for that matter. However, Java makes the signature of these method way more complicated than their Scala’s counterparts.

In order words, this is the same as the following in Scala:

Note that I am keeping the same generic type names.

.flatMap is worst.

In Scala we write:

In both languages, we could use .get() to extract value from the Optional, however, this operation is discourage since this could end on an exception in both languages. To avoid this, Java and Scala take different approaches.

In Java we need to use .orElse to supply a default value if the wrapped value is null.

In Scala we use .getOrElse

As we can see, both approaches are similar, even though Scala is more concise how to create the Optional value and how it avoids null problems.

There is another point where Java is short, Java Optional is not foldable.

Every time we put a value inside an optional value at some point we will want to know what kind of value we have in there. Is it null or it is just a regular value?

Java, once again, chooses the verbose, less convenient path.

Because Scala Option is foldable, we can do this in a more elegant way. Let’s see how.

The .fold signature in Scala is the following:

Notice that _ifEmpty: => B_ is the same as _Supplier<B>_ in Java.

So the question is why they did not add .fold to Java Optional?

For education purpose only, let’s create a FoldableOptional in Java ourselves and see how easy is to have implemented .fold.

As we can see here, the .fold implementation cannot be simpler, given the limited toolbox we have in Java; still, very straight forward.

Conclusions

Even though the Java language has been evolving in the last couple of years, it is still far behind of others such as Scala, especially in the functional side. It is very impressive how Scala maintain the same API throughout entire libraries with solid consistency. Even open source libs and projects use the same standards all across. On the other hand, Java is giving the right steps towards a better Java (if that actually exist) but there is a long way to go. In the meantime, we have to continue to use the tool on hand to do our daily jobs, so let’s use the good while continue to enhance it.