Optional class

Things to remember :

  • Use ofNullable() and do not use of() since it can through null pointer exception
  • Always use orElse() or orElseGet
javadocs
  • Java 8 has introduced a new class Optional in java.util package. It can help in writing a neat code without using too many null checks. 
  • By using Optional, we can specify alternate values to return or alternate code to run.
  • This makes the code more readable because the facts which were hidden are now visible to the developer.

Practical User :

  • We can easily make a null check on findFirst and find any using orElse method of optional
    • T orElse(T other)

Methods

  • T orElse(T other)
  • T get()
  • boolean isPresent()

Example :

package com.demo;

import java.util.Optional;
import java.util.stream.Stream;

public class Example {

	public static void main(String[] args) {

		String nullvalue = null;
		String runtimeString = "Hello";

		Emp empNull = null;
		Emp emp = new Emp("Tyson", 18);
		Emp empValueNull = new Emp(null, null);
		Emp empValueAgeNull = new Emp("Tyson", null);

		// Checking if value exist no explicit null check required-isPresent

		boolean doesExist = Optional.ofNullable(nullvalue).isPresent();
		System.out.println(doesExist);

		// Getting value from Optional //else return default value or execute method or
		// throw an exception
		String output1 = Optional.ofNullable(runtimeString).orElse("Empty"); // returning type
		String output2 = Optional.ofNullable(runtimeString).orElseGet(() -> "Empty"); // performing Lamda Supplier
		String output3 = Optional.ofNullable(runtimeString).orElseThrow(IllegalArgumentException::new); // Throw an
																										// exception if
																										// empty
		String output4 = Optional.ofNullable(runtimeString)
				.orElseThrow(() -> new IllegalArgumentException("Null found data exceptted")); // Throw an exception
																								// with message
		System.out.println(output1);

		// Performing operation if data is present
		Optional.ofNullable(runtimeString).ifPresent(System.out::println);

		// Using Map to get value out of object in optional
		int age1 = Optional.ofNullable(emp).map(Emp::getEmpAge).orElse(10);// directly a type is returned
		int age2 = Optional.ofNullable(emp).map(Emp::getEmpAge).orElseGet(() -> 10);// a supplier lamda can be execute
																					// here or method can be called
		int age3 = Optional.ofNullable(emp).map(Emp::getEmpAge).orElseThrow(IllegalArgumentException::new);// a supplier
																											// lamda can
																											// be
																											// execute
																											// here
		// Above can be done using get but always orElse is preffered

		System.out.println("================================================");
		// No need to worry about null pointer exception anymore
		boolean test1 = Optional.ofNullable(nullvalue).filter(x -> x.concat("World").equalsIgnoreCase("HelloWorld"))
				.isPresent();// beauty
		boolean test2 = Optional.ofNullable(runtimeString).filter(x -> x.concat("World").equalsIgnoreCase("HelloWorld"))
				.isPresent();
		System.out.println(test1 + " " + test2);
		// Doing the same with Objects
		boolean objTest1 = Optional.ofNullable(empNull).filter(x -> x.getEmpName().startsWith("T")).map(Emp::getEmpAge)
				.isPresent();
		boolean objTest2 = Optional.ofNullable(emp).filter(x -> x.getEmpName().startsWith("T")).map(Emp::getEmpAge)
				.isPresent();
		// Null pointed exception on below because x.getEmpName() returns null
//		boolean objTest3 = Optional.ofNullable(empValueNull).filter(x->x.getEmpName().startsWith("T")).map(Emp::getEmpAge).isPresent();

		System.out.println("================================================");

		Integer temp1 = 10;
		Integer temp2 = 20;
		Integer temp3 = 30;

		// allMatch Null check and check for single condition
		boolean tempResult1 = Stream
				.of(Optional.ofNullable(temp1), Optional.ofNullable(temp2), Optional.ofNullable(temp2))
				.filter(Optional::isPresent).allMatch(x -> x.get().equals(10));
		System.out.println(tempResult1);

		// anyMatch Null check and check for single condition
		boolean tempResult2 = Stream
				.of(Optional.ofNullable(temp1), Optional.ofNullable(temp2), Optional.ofNullable(temp2))
				.filter(Optional::isPresent).anyMatch(x -> x.get().equals(10));
		System.out.println(tempResult2);

		// noneMatch Null check and check for single condition
		boolean tempResult3 = Stream
				.of(Optional.ofNullable(temp1), Optional.ofNullable(temp2), Optional.ofNullable(temp2))
				.filter(Optional::isPresent).anyMatch(x -> x.get().equals(10));
		System.out.println(tempResult3);

		System.out.println("================Chaining Null Check================================");

		String nullValue1 = null;
		String nullValue2 = null;
		String nullValue3 = null;

		
		boolean nullCheckChain1 = Optional.ofNullable(nullValue1)
									.map(x ->  nullValue2) 
									.map(x -> nullValue3) 
									.isPresent();
		
		System.out.println(nullCheckChain1);
		
		
				// Reference :
		// https://stackoverflow.com/questions/55139648/chaining-multiple-java-optionals

		String nonNullValue1 = "abc";
		String nonNullValue2 = "abc";
		String nonNullValue3 = "abc";

		boolean nullCheckChain2 = Optional.ofNullable(nonNullValue1)
				.map(x ->  nonNullValue2) 
				.map(x -> nonNullValue3) 
				.isPresent();
		System.out.println(nullCheckChain2);
		
		
		//2nd way without optinal to chain and null check
		boolean nullCheckChain3 = Stream.of(nullValue1, nullValue2, nullValue3).allMatch(x -> x != null);

		System.out.println(nullCheckChain3);


	}
}

class Emp {
	private String empName;
	private Integer empAge;

	public Emp(String empName, Integer age) {
		super();
		this.empName = empName;
		this.empAge = age;
	}

	public String getEmpName() {
		return empName;
	}

	public Integer getEmpAge() {
		return empAge;
	}
}

Good Reference : baeldung

Leave a Comment