Optional finallyLearned()

Optional<Learn> finallyLearned!

Yes, this is a post about my long journey with Optionals.


Optionals have been around for quite a long time. They came with Java 8, what makes  them almost as long in the industry as... I am, actually, since the first thing I had to do in my first job was learning those strange Stream thingy. Even though so much time passed, I never really saw a purpose for Optionals. That is of course, because I couldn't use them the way intended. At first I wanted to use them exactly like old if-else statements, so:

Ugly, isn't it? Considering myself being so edgy, so robust, so futuristic was dimmed by simple thought - why not use basic if-else? What were those silly Optionals thinking? Isn't it reinventing the wheel? Also not being able to chain isPresent() method with orElse() was a total misunderstanding for me. "Of course I would like to cover all possibilities, why can't I with easy syntax?" - I thought. Suddenly, with Java 11 there appeared method ifPresentOrElse() but still - nothing better the plain-old if-else statement.


what of course evaluates to existing cat and no dog.

Also there is get() method, which is used to retrieve the value. But you have to check first, if Optional has a value to return, otherwise it will return NoSuchElementException, which is Optional equivalent for NullPointerException... So it's the same stuff. I haven't found any reason to use Optional, until recently. I started to dig a little bit deeper. And I found something good.


Retrieving data

Let's study this example. Let's have a situation described as such:
School has a Classroom. 
Classroom has a Desk.
Each desk belongs to User/has owner.
Each User has it's own name.

And we want to retrieve a name. How to do it, with null checking by the way? The old way is clumsy and messy.

And how to do it with Optionals? Optionals syntax makes this kind of tasks easy, functional, very readable and sexy. I love how easily functions can be chained and in case of any nasty null - there is a downfall. Java 8 provides method like map(), filter(), flatMap() and from Java 9 Optionals can be changed into Stream, which is further improvement.


Optional parameters

Consider such a method
I believe it is much more readable than the same thing with if-else statement or, gods above!, using ternary operator with null. I tend to use this approach in every possible update method of my entities since usually I want them to be updated only if new value has been provided. So I simply copy entity and if any new value is present - set it. I find it very clean.


Pitfalls

There are some pitfalls I encountered while playing with Optionals. Learn from my mistake!

  1. get() is not safe. It will throw NoSuchElementException. At the beginning I forgot about it quite a lot. But using more functional approach, as shown above, might using this method useless, since you can end with alternative (bad) scenario method like...
  2. orElse(), orElseGet(). Why those two are here? Only because it took me some time to realize the difference. So... orElse() takes a value, but sometimes you just pass a method there, like so:
  3. so what will happen there? If the location exists it will return its name, right? Well... yes, but first it must know the value of willReturnSomeLocation(). What does that mean? If there is some other operation inside this method, let me exaggerate, throwBomb() - it will happen. And after that, the correct value will be returned. It is very logical if you think about it, since hey, it's Java, we do not pass function, we pass values that those function counts. But I caught myself with this one. On the other hand, method orElseGet() take a Supplier, so it will happen only if value is not present.


All right, thank you for staying with me and reading my experiences with Optionals. If you would like to add your thoughts, comment or talk about it, feel free to contact me.

Komentarze

Popularne posty z tego bloga

Java EE 8 & Wildfly 17 & RestEasy setup

Testing: jUnit's TemporaryFolder

Two entities coexisting in one table