Wednesday, May 28, 2014

Java 8's Optional frustrations

At my current project we started working with Java 8 this week. Mainly because of the new Streaming Api so we could do some functional coding in Java and get rid of the Google Guava dependency (which I kind of introduced some weeks ago, because, well, I just hate doing for-loops and null-checks. Once you’ve done Scala you don’t want to go back ;-).
Being used to work with Scala’s Option, I eagerly got started to remove all null-checks and start working with Java’s Optional. The Optional is a nice addition but after working with it for a few days I feel it is dead-wrong in 2 basic and primary methods:

1. To create an Optional, you use Optional.of(..). I threw in a value which could be null and immediately got a NPE. Apparently there is an Optional.ofNullable() method. WTF!! I cannot think of any reason why the ‘of’ method should not accept null’s. Why oh why would you otherwise want to use an Optional if you know the value is never null ! Having to use ‘ofNullable’ is just unnecessary typing and is polluting the code. The ‘of’ method is just useless.

2. Working with requests and contexts, I sometimes want to get one attribute, but, if it’s not set, I want to fall back to another attribute which also might not be set. So, I want to create an Optional and use ‘orElse’ to use another optional value. However, in Java the Optional.orElse returns ’T’ and not an ‘Optional<T>’. In contrast to Scala's Option which ‘orElse’ does return ‘Option[T]’. The ‘Optional.orElse’ method is really a ‘getOrElse’ returning the value of the Optional or an alternative. A real ‘orElse’ function is just missing. I don’t want the value T, I want to keep working with the Optional in a functional way. Now, to get around this you have to do something like this:
Optional.ofNullable(Optional.ofNullable(getValueA()).orElse(getValueB())). How is that for readability? 

Besides these clear mistakes (IMHO) I regret the Optional has not found it’s way into some other classes, like a Map.getOptional method for example, to be able to get Optional instances right away instead of having to do the wrapping yourself.