A Brief Introduction of Optional Class in Java 8

Posted By Gourav Kumar | 30-May-2019

Till java 7, if someone tells you for the null check to handle NullPointerException in your application then you can use this simple conditional statement which is given below:

if(obj != null){
//Code Here
}
        

But it is not guaranteed to handle NullPointerException.

Since Java 8 introduced a new class Optional which main purpose is to avoid NullPointerException and develop a neat and clean java application.

Advantage of Java 8 Optional class:

i) No more null checks needed.

ii) No more NullPointerException.

iii) No need Boiler plate code.

The disadvantage of Java 8 Optional class:

i) Optional class can’t able to make serializable because it is a value-based class, but if you want to use this class with serializable then you can use Guava Optional API.

1) Optional class basic methods use:

i) of(T obj):- If you definitely sure that the reference variable doesn’t contain a null value in any condition then you can use it otherwise you will get NullPointerException.

ii) empty() :- If you want to use empty Optional object then you can use it.

iii) ofNullable(T obj):- If you know that the reference variable may contain null value then, in that case, you can use it. In the case of null value, it will return Optional .empty.

Note: All the above methods are static factory methods of Optional class.

Example:


package com.oodles;
import java.util.Optional;
public class MyClass {
    public static void main(String args[]) {

        Optional gender = Optional.of("MALE");
        String answer1 = "Yes";
        String answer2 = null;

        System.out.println("Non-Empty Optional:" + gender);
        System.out.println("Non-Empty Optional: Gender value : " + gender.get());
        System.out.println("Empty Optional: " + Optional.empty());

        System.out.println("ofNullable on Non-Empty Optional: " + Optional.ofNullable(answer1));
        System.out.println("ofNullable on Empty Optional: " + Optional.ofNullable(answer2));
        System.out.println("ofNullable on Non-Empty Optional: " + Optional.of(answer2));

    }
}

 

Output:

Non-Empty Optional:Optional[MALE]
Non-Empty Optional: Gender value : MALE
Empty Optional: Optional.empty
ofNullable on Non-Empty Optional: Optional[Yes]
ofNullable on Empty Optional: Optional.empty
Exception in thread "main" java.lang.NullPointerException
	at java.base/java.util.Objects.requireNonNull(Objects.java:221)
	at java.base/java.util.Optional.<init>(Optional.java:107)
	at java.base/java.util.Optional.of(Optional.java:120)
	at MyClass.main(MyClass.java:15)

2) Optional additional methods given below:

i) map(java.util.function.Function<T,R> function): this method is use to transform the value of Optional class in java.

ii) flatMap(java.util.function.Function<T,R> function): this method is use to transform the value of Optional just like map(java.util.function.Function<T,R>) and remove the one level from nested Optional objects.

Example:

package com.oodles;
import java.util.Optional;
public class MyClass {
    public static void main(String args[]) {

        Optional nonEmptyGender = Optional.of("male");
        Optional emptyGender = Optional.empty();

        System.out.println("Non-Empty Optional:: " + nonEmptyGender.map(String::toUpperCase));
        System.out.println("Empty Optional    :: " + emptyGender.map(String::toUpperCase));

        Optional> nonEmptyOtionalGender = Optional.of(Optional.of("male"));
        System.out.println("Optional value   :: " + nonEmptyOtionalGender);
        System.out.println("Optional.map     :: " + nonEmptyOtionalGender.map(gender -> gender.map(String::toUpperCase)));
        System.out.println("Optional.flatMap :: " + nonEmptyOtionalGender.flatMap(gender -> gender.map(String::toUpperCase)));


    }
}
        

Output:

Non-Empty Optional:: Optional[MALE]
Empty Optional :: Optional.empty
Optional value :: Optional[Optional[male]]
Optional.map :: Optional[Optional[MALE]]
Optional.flatMap :: Optional[MALE]

 

iii) filter(java.util.function.Predicate<T> predicate): this Optional class method is used to return value on the basis of passing predicate expression as an argument if predicate expression match then returns Optional value otherwise Optional.empty.

 

Example:

package com.oodles;
import java.util.Optional;
public class MyClass {
    public static void main(String args[]) {

        Optional gender = Optional.of("MALE");
        Optional emptyGender = Optional.empty();

        System.out.println(gender.filter(g -> g.equals("male")));
        System.out.println(gender.filter(g -> g.equalsIgnoreCase("MALE")));
        System.out.println(emptyGender.filter(g -> g.equalsIgnoreCase("MALE")));


    }
}
       

Output:

Optional.empty
Optional[MALE]
Optional.empty

 

iv) isPresent(): this method of Optional class is use to return boolean value, if Optional object is non-empty then return true otherwise false.

 

v) ifPresent(java.util.function.Consumer<T> consumer): this method of Optional class is use to performs given action if the given Optional object is non-empty otherwisenot.

Example:

package com.oodles;
import java.util.Optional;
public class MyClass {
    public static void main(String args[]) {

        Optional gender = Optional.of("MALE");
        Optional emptyGender = Optional.empty();

        System.out.println(gender.isPresent()?"Value present":"Value not present");

        gender.ifPresent(g -> System.out.println("Gender available"));
        emptyGender.ifPresent(g -> System.out.println("Gender available"));


    }
}
        

Output:

Value present
Gender available

 

vi) orElse(T obj): this method of Optional class is used to return Optional object value, if it is non-empty otherwise return the value pass in it.

 

Vii) orElseGet(java.util.function.Supplier<T> supplier): this method of Optional class is use to accept Supplier functional interface implemention and return the supplier value.

Example:

package com.oodles;	   
import java.util.Optional;
public class MyClass {
    public static void main(String args[]) {

        Optional gender = Optional.of("MALE");
        Optional emptyGender = Optional.empty();

        System.out.println(gender.orElse("FEMALE")); 
        System.out.println(emptyGender.orElse("FEMALE"));

        System.out.println(gender.orElseGet(() ->"FEMALE"));
        System.out.println(emptyGender.orElseGet(() ->"FEMALE"));


    }
}
        

Output:

MALE
FEMALE
MALE
FEMALE

 

Conclusion:

 

You can use Optional class at following places given below:

i) Method Arguments

ii) Method Return Type

iii) Variable declaration but remember if you use any bean in the serializable environment then it is not useful in that case.

iv) Class level to specify generic support.

Request for Proposal

Recaptcha is required.

Sending message..