Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

A Look at Java Optionals

DZone 's Guide to

A Look at Java Optionals

Check out this post to learn more about Java Optionals.

· Java Zone ·
Free Resource

Optional is a container object that may or may not contain a non-null value. If a value is present, isPresent() will return true and get() will return the value.

Package : java.util
public final class Optional<T>
extendsObject


The following is a list of useful methods in the Optional class:

1. Create Optional-Related Methods

Methods: Optional.of,  Optional.ofNullable,  Optional.empty():

Optional<String> emptyOptional = Optional.empty();
Optional<String> nonEmptyOptional = Optional.of("name"); // this will not work with null value
Optional<String> nonEmptyOptional = Optional.ofNullable(null); // this will work fine with null value


2. Check the Optional Value

Methods: Optional.isPresent()Optional.ifPresent() 

  •  isPresent() returns true if Optional has values.
Optional<String> nonEmptyOptional = Optional.of("name");
assertTrue(nonEmptyOptional.isPresent());


  •   ifPresent() = execute a block of code if the value is present.

We have the following null value check inside the method before Optional.

if(data == null){
     System.out.println( " data is " + data);
}
// data is object used inside method


In this way, when it comes to null check, we cannot guarantee that "data" will not be used without null check, and it can cause NullPointerException, if checks are not added before using it.

Now, with this Optional introduction, we can use ifPresent for similar needs.

Optional<String> nonEmptyOptional = Optional.of("name");
nonEmptyOptional.ifPresent( x->    {System.out.println(x.length());});


3. Get Value From Optional and Related Methods

  •  get() = returns value wrapped in Optional.
Optional<String> nonEmptyOptional = Optional.ofNullable("orignal");
String value = nonEmptyOptional.get();


  •  orElse() = return a default value if value not present
// orElse getting used as Optional has null value.
Optional<String> emptyOptional = Optional.ofNullable(null);
String value = emptyOptional.orElse("default Value");
assertEquals("default Value", value);

// orElse not getting used as Optional has non null value.
Optional<String> nonEmptyOptional = Optional.ofNullable("orginal");
String value1 = nonEmptyOptional.orElse("default Value");
assertEquals("orginal", value1);


  •  orElseGet() = this is similar to orElse(). Just instead of taking value, it takes the supplier function as the input when a value is not present in Optional.
// orElse getting used as Optional has null value.
Optional<String> emptyOptional = Optional.ofNullable(null);
String value = emptyOptional.orElseGet(()->"default value");
assertEquals("default value", value);

// orElse not getting used as Optional has non null value.
Optional<String> nonEmptyOptional = Optional.ofNullable("orginal");
String value1 = nonEmptyOptional.orElseGet(()->"default value");
assertEquals("orginal", value1);


  •  orElseThrow() = Similar to orElseGet; it throws an exception in cases where values are null.
@Test(expected = NullPointerException.class)
public void OrElseThrowCheck() {
    String nullName = null;
    String value = Optional.ofNullable(nullName).orElseThrow(
      NullPointerException::new);
}


4. Optional Usage

  • Using Optional as a return value.

One common usage of Optional is to return an Optional wrapper from a method. When you define a method, it can return the null value or Object based on method logic. It is a good approach to return the Optional Object so that while using a method, the developer knows that the return value can be null. It forces the developer to handle a return Object gracefully. The beauty of the Optional class is that it guides users to do proper checks and avoid NullPointerException.

The following example defines the method "Optional<Employee>getEmployeeWithId(int id)," which returns  Optional<Employee> , and the caller function has to use one of the Optional methods to get the value, and in process, it makes sure that NullPointerExceptions are avoided.

static List<Employee> employess = new ArrayList<>();

public static void main(String[] args) throws EmployeeNotFoundException {
  employess.add(new Employee("emp1", 1, 1000));
  employess.add(new Employee("emp2", 2, 2000));
  employess.add(new Employee("emp1", 3, 3000));

  Optional<Employee> employee = getEmployeeWithId(1);
  Employee e = employee.orElseThrow(() -> new EmployeeNotFoundException("emp not found"));
  System.out.println(e);
}

public static Optional<Employee> getEmployeeWithId(int id) {
  Optional<Employee> employee = employess.stream().filter(e -> (e.getId() == id)).findFirst();
  return employee;
}


  • Using Optional as an argument to a method.

It is not advisable, nor correct, to use Optional as an argument to the method. Suppose we have a method that takes two arguments: One is Optional and one is non- Optional. The idea behind using Optional as one argument can be to support the null value of the Optional argument.

Use the overloaded method instead of using Optional an argument to the method.

Instead of using Optional as an argument to support the null value of that argument, it is best to define one more overloaded method without the second argument.

public static Optional<Employee> getEmployee(int id,Optional<String> name) {
............
return employee;
}

//Better approach  - User overloaded methods
public static Optional<Employee> getEmployee(int id,String name) 
public static Optional<Employee> getEmployee(int id)


5. List of New Methods Added to Optional Class in Newer Java Versions

  • Java 9
    •  or() — If a value is present, it returns an Optional describing the value; otherwise, it returns an Optional produced by the supplying function.
    •  ifPresentOrElse(Consumer<? super T>action, Runnable emptyAction) — If a value is present, performs the given action with the value, otherwise performs the given empty-based action.
    •  stream()— If a value is present, it returns a sequential Stream containing only that value; otherwise, it returns an empty Stream.
  • Java 10
    •  orElseThrow() — If a value is present, it returns the value; otherwise, it throws a NoSuchElementException. It does not accept any argument as Java version 8.
  • Java 11
    •  isEmpty() — If a value is not present, it returns true; otherwise, it is false.

6. Complete Source Code

Please use following Git link to refer source code.         

Note : Optional is a value-based class; use of identity-sensitive operations (including reference equality (==), identity hash code, or synchronization) on instances of Optional may have unpredictable results and should be avoided.

7. References

Below are the Java docs for various versions:

Topics:
java ,optionals ,methods ,value ,null ,nullpointerexception ,tutorial ,optionals in java ,versions

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}