NullPointerException can be annoying in Java, and the designer even regretted inventing it, calling it as "my billion-dollar mistake". Luckily Optional class was introduced in Java 8, making it an incredible useful tool to get ride of the NullPointerException and verbose codes.
Suppose you are designing a model of the person. Each person may or may not has a house. But each house must have an address. You will probably write the following codes:
Now if you would like to get the address from a person, you could write the function like this:
Here we did two null checks to make sure we can get the address from a person. Frankly speaking, we can add null checks whenever we need it, to get rid of the NullPointerException. However, sometimes those are not reflecting the detail of our design. The readers of above codes may wonder whether the address string could be null, thus may add redundant null check for the return value of the function.
Now let's apply the optional class to the place where the value CAN be null.
Then we can rewrite our function as:
Line 3 converts the Person to Optional<Person>
Line 4 translates Optional<Person> to Optional<House>
Line 5 maps Option<House> to Optional<String>
Line 6 gets string value and if nothing there, returns None.
What's the difference between flatMap and map? Let me use a diagram to demonstrate that.
flatMap operation will extract the content inside the wrapping box and apply the map. Since getHouse function returns a Optional<House>, we should use flatMap. Otherwise we will get an Optional<Optional<House>>. As getAddress will simply return a string, we can directly use map operation.
Things got more interesting if we are dealing with a list of persons. This function will get a set of addresses from a list of persons.
Here firstly we wrap each Person object into a Optional<Person>, then we convert Optional<Person> all the way to Optional<String>. Please note some of them may have real string but some may not. So we apply Optional::stream to convert them to either streams with 1 item or empty streams. A stream flatMap function will extract the real object behind Optional streams and put them into a stream, which is finally collected into a set.
Naturally Optional provides get function to get the value of the item, but will throw out a NullPointerException if the item is missing. Then we will probably do the same approach as null check.
Things get better if you use the orElse function.
Suppose you would like to do something if house is present, and throws an exception when the item is missing. You can use the ifPresentOrElse as following:
Now if you would like to print out the house information if a person 18 above, apply the filter:
Comentarios