Java Streams - Java Optional








Java 8 has introduced an java.util.Optional<T> class to deal with NullPointerException gracefully.

An Optional is a wrapper for a non-null value that may or may not contain a non-null value.

Methods that may return null should return an Optional instead of null.

The isPresent() from Optional<T> returns true if it contains a non-null value, false otherwise.

get() method returns the non-null value if it contains a non-null value, and throws a NoSuchElementException otherwise.

When a method returns an Optional, you must check if it contains a non-null value before asking it for the value.

If get() method is called before making sure it contains a non-null value, a NoSuchElementException is thrown out instead of a NullPointerException.





Create Optional Object

The Optional<T> class provides three static factory methods to create Optional objects.

  • <T> Optional<T> empty()
    Returns an empty Optional.
    The Optional<T> returned from this method does not contain a non-null value.
  • <T> Optional<T> of(T value)
    Returns an Optional containing the specified value as the non-null value.
    If the specified value is null, it throws a NullPointerException.
  • <T> Optional<T> ofNullable(T value)
    Returns an Optional containing the specified value if the value is non-null.
    If the specified value is null, it returns an empty Optional.

The following code shows how to create Optional objects:

import java.util.Optional;
//w w w  .java 2  s  .c o  m
public class Main {
  public static void main(String[] args) {
    Optional<String> empty  = Optional.empty();
    System.out.println(empty);

    Optional<String> str = Optional.of("java2s.com");
    System.out.println(str);

    String nullableString = ""; 
    Optional<String> str2  = Optional.of(nullableString);
    System.out.println(str2);
  }
}

The code above generates the following result.





Example 2

The following code prints the value in an Optional if it contains a non-null value:

import java.util.Optional;
/*  w  w w . j  av  a 2  s  .c  om*/
public class Main {
  public static void main(String[] args) {
    Optional<String> str = Optional.of("java2s.com");

    if (str.isPresent()) {
      String value = str.get();
      System.out.println("Optional contains " + value);
    } else {
      System.out.println("Optional is  empty.");
    }
  }
}

The code above generates the following result.

Optional ifPresent

ifPresent(Consumer<? super T> action) method from the Optional class takes an action on the value contained in the Optional.

If the Optional is empty, this method does not do anything.

The following code prints out the contents from Optional.

import java.util.Optional;

public class Main {
  public static void main(String[] args) {
    Optional<String> str = Optional.of("java2s.com");

    str.ifPresent(value -> System.out.println("Optional contains " + value));
  }
}

The code above generates the following result.

If the Optional were empty, the code would not print anything.

Optional Value

The following are four methods to get the value of an Optional:

  • T get()
    Returns the value contained in the Optional. If the Optional is empty, it throws a NoSuchElementException.
  • T orElse(T defaultValue)
    Returns the value contained in the Optional.
    If the Optional is empty, it returns the specified defaultValue.
  • T orElseGet(Supplier<? extends T> defaultSupplier)
    Returns the value contained in the Optional.
    If the Optional is empty, it returns the value returned from the specified defaultSupplier.
  • <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X extends Throwable
    Returns the value contained in the Optional.
    If the Optional is empty, it throws the exception returned from the specified exceptionSupplier.

OptionalInt, OptionalLong, and OptionalDouble deal with optional primitive values.

  • getAsInt() method from OptionalInt class returns int value.
  • getAsLong() method from OptionalLong class return long value.
  • getAsDouble() method from OptionalDouble class return double value.

The getters for primitive optional classes also throw a NoSuchElementException when they are empty.

The following code shows how to use the OptionalInt class:

import java.util.OptionalInt;
/*from w ww.  jav  a 2s.c o  m*/
public class Main {
  public static void main(String[] args) {
    OptionalInt number = OptionalInt.of(2);

    if (number.isPresent()) {
      int value = number.getAsInt();
      System.out.println("Number is " + value);
    } else {
      System.out.println("Number is absent.");
    }
  }
}

The code above generates the following result.

Stream Optional Value

Some stream operations return optional. For example, the max() method in all stream classes returns an optional object. When using max() method on an empty stream the return value is an optional object with nothing inside.

By using Optional class we can handle the return value from those methods gracefully.

The following code shows how to use Optional object returned form max().

import java.util.OptionalInt;
import java.util.stream.IntStream;
//from  w w  w  .j a  v a  2 s. co m
public class Main {
  public static void main(String[] args) {

    OptionalInt maxOdd = IntStream.of(10, 20, 30).filter(n -> n % 2 == 1).max();
    if (maxOdd.isPresent()) {
      int value = maxOdd.getAsInt();
      System.out.println("Maximum odd  integer is " + value);
    } else {
      System.out.println("Stream is  empty.");
    }
  }
}

The code above generates the following result.