Since the release of Java 8, NullPointerExceptions have been pretty common. Before Java 8, your code was probably full of “if statements” to check if a variable was null. Still, it was impossible to catch every NullPointerException out there. With Java 8, Oracle attempted to solve this issue. They didn’t invent the holy grail, but they did make our lives as developers much easier by helping prevent code smells and those nasty Exceptions. Now, if you start a new project, you should definitely use Java 8 to avoid NullPointerExceptions.
So what exactly did Oracle do to help us in our misery? They introduced Optionals. 
You may have heard of Optionals already a few times, but you maybe don’t know exactly know how to use them in the right way. If you use them in the wrong way, it is like you wouldn’t use Optionals at all. So let’s take a look how Optionals could be used.
You may have the urge to use an Optional like we do in the following example. However, this wouldn’t be much different than just using a null check, and it’s not any easier to read.
System.out.println("Is this the correct use of Optionals?")
A better way to utilize Optionals is to check first if the Optional is Present. If you don’t do that, you can also run into a NullPointerException and you don‘t win anything at all. The following example, then, is an improvement over the first:
If you are going to use Optionals like this, you can still go the old route by just checking if the value returned by the service is null or not. Because Optionals are designed to be used in a different way.
The ifPresent Method requires a Consumer Function .
“Represents an operation that accepts a single input argument and returns no result. Unlike most other functional interfaces, Consumer is expected to operate via side-effects. This is a functional interface whose functional method is accept(Object).”
However, this approach is overly complicated. If you want to print the Integer of the Optional you can instead use the shortcut orElse. This way, you have the option to print the Integer directly (or print an alternative value if the value is null). It also makes the code more readable and easier on the eyes:
The Filter method  takes a predicate as an argument and returns an Optional. This method is great for performing some checks on the Optional first, and if it matches the filter predicate you can use the value immediately or use an orElse or an orElseThrow alternative value instead.
The map method  can also be used to work with an Optional. The map method takes a function as an argument and returns an Optional. If you do not want to receive an Optional from the map method, you have to use orElse with it, as shown below:
Introducing Optionals to Java 8 was a great move by Oracle. If you are going to use Optionals in your code and try to refactor old code wherever possible, you should be able to get rid of most of your NullPointerExceptions and code smell. Optionals help developers, allowing us to not have to think about if we forgot about catching a NullPointerException since the IDE will always notify you if an Optional is used incorrectly. If you use a Code Quality Tool like SonarQube, you will notice this too.
All in all, Optionals can really help improve your code quality, but only if you use them right. So, take some time to get used to this new concept.