Java
Introduction:
In this blog we are going to observe the use of ‘optional’ feature in java 8. Optional feature of java 8 is a container object used to contain not-null objects. This class has many utility functions to facilitate code that handles values as available or unavailable instead of checking null values. In this blog we will learn about the prevention of null pointer using the optional feature of the java 8.
Why should we use of optional feature of java 8?
Do you ever get NullPointerException as a Java developer? If you are an experienced Java developer, so you may have got Null Pointer Exception at some point of time while developing a software.
You may agree that NullPointerException is a pain for both novice and expert core Java developers. You have to put a lot of defensive code to avoid NullPointerException.
So,To avoid null pointer and defensive code we can use optional feature of the java 8.
How Can I avoid null pointer exception using optional feature of the java 8?
Let’s understand with the help of an example:
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;
}
}
Create a main class named “JavaFindEmployeeMain.java”
package org.arpit.java2blog;
import java.util.ArrayList;
import java.util.List;
public class JavaFindEmployeeMain {
public static void main(String[] args)
{
List<Employee> employeeList = createEmployeeList();
Employee employee = findEmployee(employeeList,"Suraj");
System.out.println("Employee name: "+employee.getName());
}
public static Employee findEmployee(List<Employee> employeeList,String name)
{
for(Employee e:employeeList)
{
if(e.getName().equalsIgnoreCase(name))
{
return e;
}
}
return null;
}
public static List<Employee> createEmployeeList()
{
List<Employee> employeeList=new ArrayList<>();
Employee e1=new Employee("amit",21);
Employee e2=new Employee("jai",22);
Employee e3=new Employee("karan",31);
Employee e4=new Employee("arjun",18);
Employee e5=new Employee("anil",26);
employeeList.add(e1);
employeeList.add(e2);
employeeList.add(e3);
employeeList.add(e4);
employeeList.add(e5);
return employeeList;
}
}
Output:
Exception in thread “main” java.lang.NullPointerException
at org.arpit.java2blog.JavaOptionalMain.main(JavaOptionalMain.java:12)
As you can see, “Suraj” is not present in employeeList, that’s why we are getting NullPointerException here.
Do you see the issue here? As you see, 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.
So, to avoid the null pointer and defensive code we can use optional feature which are shown in the below figure.
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<Employee> employeeList = createEmployeeList();
Optional<Employee> employeeOpt = findEmployee(employeeList,"Suraj");
if(employeeOpt.isPresent())
{
Employee employee = employeeOpt.get();
System.out.println("Employee name: "+employee.getName());
}
else
{
System.out.println("There is no employee with name Suraj");
}
}
public static Optional<Employee> findEmployee(List<Employee> employeeList,String name)
{
for(Employee e:employeeList)
{
if(e.getName().equalsIgnoreCase(name))
{
return Optional.of(e);
}
}
return Optional.empty();
}
public static List<Employee> createEmployeeList()
{
List<Employee> employeeList=new ArrayList<>();
Employee e1=new Employee("amit",21);
Employee e2=new Employee("arjun",22);
Employee e3=new Employee("anil",31);
Employee e4=new Employee("jai",18);
Employee e5=new Employee("karan",26);
employeeList.add(e1);
employeeList.add(e2);
employeeList.add(e3);
employeeList.add(e4);
employeeList.add(e5);
return employeeList;
}
}
output:
There is no employee with name Suraj
You think that you could have handled null in Java Find Employee Main as well but when you return Optional from method, it means that missing value can be expected from method.
Ways to create Optional Feature Of The Java 8:
Empty Optional:
We can create empty optional object using static factory method empty
Optional<Employee> optCar = Optional.empty();
Optional from a non-null value:
We can create Optional from non-null value using static factory method of
Optional<Employee> optCar = Optional.of(employee);
If employee is null then above function will throw NullPointerException.
Optional from null or non-null value:
We can create Optional from null or non null value using static factory method ofNullable
Optional<Employee> optCar = Optional.ofNullable(employee);
How we can get value from Optional:
We 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.
Check value in Optional:
We can check if there is a value wrapped inside Optional using isPresent method.
public static void main(String[] args)
{
List<Employee> employeeList = createEmployeeList();
Optional<Employee> employeeOpt = findEmployee(employeeList,"Suraj");
if(employeeOpt.isPresent())
{
Employee employee = employeeOpt.get();
System.out.println("Employee name: "+employee.getName());
}
else
{
System.out.println("There is no employee with name Suraj");
}
}
Conditional action in Optional:
We can use "ifPresent" method to execute action if value is present in Optional.
Change main method in JavaOptionalMain as below
public static void main(String[] args)
{
List<Employee> employeeList = createEmployeeList();
Optional<Employee> employeeOpt1 = findEmployee(employeeList,"Suraj");
Optional<Employee> employeeOpt2 = findEmployee(employeeList,"Amit");
employeeOpt1.ifPresent((employee)->System.out.println("Employee name: "+employee.getName()+" found in list"));
employeeOpt2.ifPresent((employee)->System.out.println("Employee name: "+employee.getName()+" found in list"));
}
Output:
Employee name: Suraj
Employee name: Amit found in list
As you can see here, if employee name is present in the list, then only we can print the employee name else it does not perform any action.
Default value in Optional using orElse:
We can return default value in case there is no value in Optional using orElse function.
Change main method in JavaOptionalMain as below
public static void main(String[] args)
{
List<Employee> employeeList = createEmployeeList();
Optional<Employee> employeeOpt = findEmployee(employeeList,"Suraj");
Employee employee1 = employeeOpt.orElse(new Employee("Amit",0));
System.out.println("Employee name: "+employee1.getName());
Optional<Employee> employeeOpt2 = findEmployee(employeeList,"Jai");
Employee employee2= employeeOpt2.orElse(new Employee("Dummy",0));
System.out.println("Employee name: "+employee2.getName());
}
Output:
Employee name: Amit
Employee name: Jai
Default value in Optional using orElseGet
Here "orElseGet" is a lazy counter part of orElse which takes supplier as parameter and will be called only if value is not present in Optional.
Change main method in JavaOptionalMain as below
public static void main(String[] args)
{
List<Employee> employeeList = createEmployeeList();
Optional<Employee> employeeOpt = findEmployee(employeeList,"Suraj");
Employee employee1 = employeeOpt.orElseGet(()->new Employee("Amit",0));
System.out.println("Employee name: "+employee1.getName());
Optional<Employee> employeeOpt2 = findEmployee(employeeList,"Amit");
Employee employee2 = employeeOpt2.orElseGet(()->new Employee("Jai",0));
System.out.println("Employee name: "+employee2.getName());
}
Output:
Employee name: Amit
Employee name: Jai
Throwing exception from Optional
We can use orElseThrow to throw exception in case Optional is empty. It's a similar to get() method but in this case, we can choose to throw any Exception rather than "NoSuchMethodException".
Change main method in JavaOptionalMain as below
public static void main(String[] args)
{
List<Employee> employeeList = createEmployeeList();
Optional<Employee> employeeOpt = findEmployee(employeeList,"Adam");
Employee employee = employeeOpt.orElseThrow(() -> new RuntimeException("Employee not found"));
System.out.println("Employee name: "+employee.getName());
Optional<Employee> employeeOpt2 = findEmployee(employeeList,"Martin");
Employee employee1 = employeeOpt2.orElseThrow(() -> new RuntimeException("Employee not found"));
System.out.println("Employee name: "+employee1.getName());
}
Summary:
In this blog we have learned about the optional feature of java 8 and where we can use this feature. We also learned the way of the create optional and how to avoid null pointer exception and defensive code to check null pointer.
The most widely used programming language in web and mobile applications, java 8 is a light-weight clientside scripting language that our developers hold expertise in. Are you looking for development services to design web applications and build backend for your server? Look no further! We are an ERP Development company with expertise in developing customized software solutions for our clients. Our custom development services enable businesses to automate, plan, collaborate, and execute their operations methodically.