Tuesday, 16 June 2015

Java 8 and how Optional removes the need for == null

I was confused initially when the Optional concept entered the Java world.
I was wondering how the hell can Optional remove the need to check for null? At some point I will need to use optional.isPresent() before using whatever is inside. So what's the point to replace == null with isPresent()?

The main concept to keep in mind is that Optional is a monad and as a monad contains map(), flatmap(), filter() and other methods that can be used directly against the optional instance.

Here, with the following simple code, I hope I will clarify a bit more the power of java.util.Optional.

In this example we have a list of logs and we want to apply 3 different operations based on the the type of log (INFO, ERROR, WARN).

package com.marco.optional;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

public class TestOptional {

        public static void main(String[] args) {
                List<Optional<String>> logs = new ArrayList<Optional<String>>();
                logs.add(Optional.ofNullable("INFO:: some info here 1"));
                logs.add(Optional.ofNullable("INFO:: some info here 2"));
                logs.add(Optional.ofNullable("ERROR:: some error here 3"));
                logs.add(Optional.ofNullable("INFO:: some info here 4"));
                logs.add(Optional.ofNullable("WARN:: some info here 5"));
                logs.add(Optional.ofNullable("INFO:: some info here 7"));
                logs.add(Optional.ofNullable("WARN:: some info here 8"));

                for (Optional<String> singleLog : logs) {


        public static void printErrors(Optional<String> singleLog) {
                singleLog.filter(entry -> entry.startsWith("ERROR")).ifPresent(System.out::println);

        public static void printInfos(Optional<String> singleLog) {
                singleLog.filter(entry -> entry.startsWith("INFO")).ifPresent(System.out::println);

        public static void printWarnOnlyNumber(Optional<String> singleLog) {
                singleLog.filter(entry -> entry.startsWith("WARN"))

                          .map(warn -> warn.substring(warn.length() - 1))


Output :

INFO:: some info here 1
INFO:: some info here 2
ERROR:: some error here 3
INFO:: some info here 4
INFO:: some info here 7

No == null and no if

Optional takes care of it for you ;)

No comments:

Post a Comment