Java 8 Optional: A way to avoid NullPointerException
Tags: java, programming, java8
Published: 2019-04-11 17:26:58

---
title: Java 8 Optional: A way to avoid NullPointerException
published: true
description: 
tags: #java #programming #java 8
---

In this post, we will see about Java 8 optional.

Did you ever get <a href="https://java2blog.com/java-lang-nullpointerexception/" target="_blank" rel="noopener"><strong>NullPointerException</strong></a> as Java developer? If you are experienced Java developer, you might have got NullPointerException at some point of time.
You might agree that NullPointerException is pain for novice or expert <a href="https://java2blog.com/core-java-tutorial-for-beginners-experienced/" target="_blank" rel="noopener">core java</a> developer. You have to put a lot of defensive code in case you want to avoid NullPointerException.
Let's see with the help of an example.
<pre class="java" name="code">package org.arpit.java2blog;

public class Employee {
	private String name;
	private int age;
	
	public Employee(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
}
</pre>
Create a main class named "JavaFindEmployeeMain.java"
<pre class="java" name="code">package org.arpit.java2blog;
 
import java.util.ArrayList;
import java.util.List;
 
public class JavaFindEmployeeMain {
	
	public static void main(String[] args)
	{
		List&lt;Employee&gt; employeeList = createEmployeeList();
		Employee employee = findEmployee(employeeList,"Adam");
		System.out.println("Employee name: "+employee.getName());
	}
	
	public static Employee findEmployee(List&lt;Employee&gt; employeeList,String name)
	{
		for(Employee e:employeeList)
		{
			if(e.getName().equalsIgnoreCase(name))
			{
				return e;
			}
		}
		return null;
	}
	public static List&lt;Employee&gt; createEmployeeList()
	{
		List&lt;Employee&gt; employeeList=new ArrayList&lt;&gt;();
		
		Employee e1=new Employee("John",21);
		Employee e2=new Employee("Martin",22);
		Employee e3=new Employee("Mary",31);
		Employee e4=new Employee("Stephan",18);
		Employee e5=new Employee("Gary",26);
		
		employeeList.add(e1);
		employeeList.add(e2);
		employeeList.add(e3);
		employeeList.add(e4);
		employeeList.add(e5);
		
		return employeeList;
		
	}
}
</pre>
When you run above program, you will get below output:
<div style="padding: 12px; background-color: #faf2ac; line-height: 1.4;">Exception in thread "main" java.lang.NullPointerException
at org.arpit.java2blog.JavaOptionalMain.main(JavaOptionalMain.java:12)</div>
As you can see, "Adam" is not present in employeeList, that's why we are getting NullPointerException here.

Do you see the issue here? We forgot to check null when we tried to find employee in the list. This occurs more often when you call library function and it returns null and you forget to check it.

<hr />

<h2><span style="color: #800000;">Java 8 Optional</span></h2>
You can use Optional to solve this problem. You can change "JavaOptionalMain" as below.
<pre class="java" name="code" mark="13,25,31,34">package org.arpit.java2blog;
 
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
 
public class JavaOptionalMain {
	
	public static void main(String[] args)
	{
		List&lt;Employee&gt; employeeList = createEmployeeList();
		Optional&lt;Employee&gt; employeeOpt = findEmployee(employeeList,"Adam");
		if(employeeOpt.isPresent())
		{
			Employee employee = employeeOpt.get();
			System.out.println("Employee name: "+employee.getName());
		}
		else
		{
			System.out.println("There is no employee with name Adam");
		}
	}
	
	public static Optional&lt;Employee&gt; findEmployee(List&lt;Employee&gt; employeeList,String name)
	{
		for(Employee e:employeeList)
		{
			if(e.getName().equalsIgnoreCase(name))
			{
				return Optional.of(e);
			}
		}
		return Optional.empty();
	}
	public static List&lt;Employee&gt; createEmployeeList()
	{
		List&lt;Employee&gt; employeeList=new ArrayList&lt;&gt;();
		
		Employee e1=new Employee("John",21);
		Employee e2=new Employee("Martin",22);
		Employee e3=new Employee("Mary",31);
		Employee e4=new Employee("Stephan",18);
		Employee e5=new Employee("Gary",26);
		
		employeeList.add(e1);
		employeeList.add(e2);
		employeeList.add(e3);
		employeeList.add(e4);
		employeeList.add(e5);
		
		return employeeList;
	}
}
</pre>
When you run above program, you will get below output:
<div style="padding: 12px; background-color: #faf2ac; line-height: 1.4;">There is no employee with name Adam</div>
You might think that you could have handled null in JavaFindEmployeeMain as well but when you return Optional from method, it means that missing value can be expected from method.
<img class="aligncenter wp-image-5578 size-full" src="https://java2blog.com/wp-content/uploads/2018/05/Optional.jpg" alt="Optional Java 8" width="443" height="218" />

<hr />

<h2><span style="color: #800000;">Ways to create Optional</span></h2>
There are multiple ways to create Optional.
<h3>Empty Optional</h3>
You can create empty optional object using static factory method "empty"
<pre class="java" name="code">Optional&lt;Employee&gt; optCar = Optional.empty();
</pre>
<h3>Optional from a non-null value</h3>
You can create Optional from non-null value using static factory method "of"
<pre class="java" name="code">Optional&lt;Employee&gt; optCar = Optional.of(employee);
</pre>
If employee is null then above method will throw NullPointerException.
<h3>Optional from null or non-null value</h3>
You can create Optional from null or non null value using static factory method "ofNullable"
<pre class="java" name="code">Optional&lt;Employee&gt; optCar = Optional.ofNullable(employee);
</pre>

<hr />

<h2><span style="color: #800000;">Getting value from Optional</span></h2>
You can use get() method to retrieve value from Optional but it is least safe. If value is not present then it will throw NoSuchElementException, so you need to make sure you call isPresent() method before you call get() method.

<hr />

<h2><span style="color: #800000;">Check value in Optional</span></h2>
You can check if there is value wrapped inside Optional using isPresent method.
<pre class="java" name="code">    public static void main(String[] args)
	{
	        List&lt;Employee&gt; employeeList = createEmployeeList();
		Optional&lt;Employee&gt; employeeOpt = findEmployee(employeeList,"Adam");
		if(employeeOpt.isPresent())
		{
			Employee employee = employeeOpt.get();
			System.out.println("Employee name: "+employee.getName());
		}
		else
		{
			System.out.println("There is no employee with name Adam");
		}
	}
</pre>

<hr />

<h2><span style="color: #800000;">Conditional action in Optional</span></h2>
You can use ifPresent method to execute action if value is present in Optional.
Change main method in JavaOptionalMain as below
<pre class="java" name="code">      
    public static void main(String[] args)
	{
		List&lt;Employee&gt; employeeList = createEmployeeList();
		Optional&lt;Employee&gt; employeeOpt1 = findEmployee(employeeList,"Adam");
		Optional&lt;Employee&gt; employeeOpt2 = findEmployee(employeeList,"John");
		
		employeeOpt1.ifPresent((employee)-&gt;System.out.println("Employee name: "+employee.getName()+" found in list"));
		employeeOpt2.ifPresent((employee)-&gt;System.out.println("Employee name: "+employee.getName()+" found in list"));

	}
</pre>
When you run this program, you will get below output:
<div style="padding: 12px; background-color: #faf2ac; line-height: 1.4;">Employee name: Dummy
Employee name: John found in list</div>
As you can see here, if employee name present in the list, then only we are printing employee name else it does not perform any action.

<hr />

<h2><span style="color: #800000;">Default value in Optional using orElse</span></h2>
You can return default value in case there is no value in Optional using orElse method.
Change main method in JavaOptionalMain as below
<pre class="java" name="code">     
    public static void main(String[] args)
	{
		List&lt;Employee&gt; employeeList = createEmployeeList();
		Optional&lt;Employee&gt; employeeOpt = findEmployee(employeeList,"Adam");
		Employee employee1 = employeeOpt.orElse(new Employee("Dummy",0));
		System.out.println("Employee name: "+employee1.getName());
		
		Optional&lt;Employee&gt; employeeOpt2 = findEmployee(employeeList,"Martin");
		Employee employee2= employeeOpt2.orElse(new Employee("Dummy",0));
		System.out.println("Employee name: "+employee2.getName());
		
	}
</pre>
When you run this program, you will get below output:
<div style="padding: 12px; background-color: #faf2ac; line-height: 1.4;">Employee name: Dummy
Employee name: Martin</div>
Please note that even if value is present in Optional, default object will be crerted.

<hr />

<h2><span style="color: #800000;">Default value in Optional using orElseGet</span></h2>
orElseGet is lazy counter part of orElse.It takes <a href="https://java2blog.com/java-8-supplier-example/">supplier</a> as parameter and will be called only if value is not present in Optional.
Change main method in JavaOptionalMain as below
<pre class="java" name="code">    
    public static void main(String[] args)
	{
		List&lt;Employee&gt; employeeList = createEmployeeList();
		Optional&lt;Employee&gt; employeeOpt = findEmployee(employeeList,"Adam");
		Employee employee1 = employeeOpt.orElseGet(()-&gt;new Employee("Dummy",0));
		System.out.println("Employee name: "+employee1.getName());
		
		Optional&lt;Employee&gt; employeeOpt2 = findEmployee(employeeList,"Martin");
		Employee employee2 = employeeOpt2.orElseGet(()-&gt;new Employee("Dummy",0));
		System.out.println("Employee name: "+employee2.getName());
		
	}
</pre>
When you run this program, you will get below output:
<div style="padding: 12px; background-color: #faf2ac; line-height: 1.4;">Employee name: Dummy
Employee name: Martin</div>

<hr />

<h2><span style="color: #800000;">Throwing exception from Optional</span></h2>
You can use orElseThrow to throw exception in case Optional is empty. It is similar to get() method but in this case, you can choose to throw any Exception rathar than NoSuchMethodException.
Change main method in JavaOptionalMain as below
<pre class="java" name="code">    public static void main(String[] args)
	{
		List&lt;Employee&gt; employeeList = createEmployeeList();
		Optional&lt;Employee&gt; employeeOpt = findEmployee(employeeList,"Adam");
		Employee employee1 = employeeOpt.orElseThrow(() -&gt; new RuntimeException("Employee not found"));
		System.out.println("Employee name: "+employee1.getName());
		
		Optional&lt;Employee&gt; employeeOpt2 = findEmployee(employeeList,"Martin");
		Employee employee2 = employeeOpt2.orElseThrow(() -&gt; new RuntimeException("Employee not found"));
		System.out.println("Employee name: "+employee2.getName());
		
	}
</pre>
<h2><span style="color: #800000;">Use of Optional in Java 8 APIs</span></h2>
There are lot of uses of Optional in Java 8 APIs.Let me provide you one example.
Stream.findFirst() method returns an Optional with the first element of this stream, or an empty Optional if the stream is empty.

That's all about Optional in <a href="https://java2blog.com/java-8-tutorial/" target="_blank" rel="noopener">Java 8</a>.

Happy learning!!