Java 9 - java.util.Optional Improvements

[Updated: Oct 27, 2017, Created: Oct 26, 2017]

Following examples show how to use new Java 9 methods added to java.util.Optional and to its primitive versions: OptionalInt, OptionalLong and OptionalDouble

(1) ifPresentOrElse(Consumer, Runnable)

This new method performs the given Consumer action if a value is present, otherwise runs the given Runnable action.

 IntStream.of(1, 2, 4)
.filter(i -> i % 3 == 0)
.findFirst()
.ifPresentOrElse(System.out::println, () -> {
System.out.println("No multiple of 3 found");
});
 No multiple of 3 found
 IntStream.of(2, 6, 8)
.filter(i -> i % 3 == 0)
.findFirst()
.ifPresentOrElse(System.out::println, () -> {
System.out.println("No multiple of 3 found");
});
 6

Comparing with Java 8 Optional.isPresent():

 OptionalInt opt = IntStream.of(1, 2, 4)
.filter(i -> i % 3 == 0)
.findFirst();
if (opt.isPresent()) {
System.out.println(opt.getAsInt());
} else {
System.out.println("No multiple of 3 found");
}
 No multiple of 3 found

Comparing with Java 8 Optional.ifPresent():

ifPresent() method does not provide an alternative action when the value is absent:

 IntStream.of(1, 2, 4)
.filter(i -> i % 3 == 0)
.findFirst()
.ifPresent(System.out::println);
  

Comparing with Java 8 Optional.orElse():

All above cases are action based. For a result assignment, we can still use orElse() method when the value is not present.

 int result = IntStream.of(1, 2, 4)
.filter(i -> i % 3 == 0)
.findFirst()
.orElse(-1);
System.out.println(result);
 -1

(2) Optional.or(Supplier)

The new method can be used to lazily produce an Optional via a Supplier when the value is not present:

 char digit = Stream.of('a', 'b', 'c')
.filter(c -> Character.isDigit(c))
.findFirst()
.or(() -> Optional.of('0')).get();
System.out.println(digit);
 0

Note that or methods are not added to OptionalInt, OptionalLong and OptionalDouble classes in Java 9.


Comparing with orElseGet()

The Java 8 Optional.orElseGet() method produces a 'value' if it is not present, whereas, or method returns an instance of Optional if value is not present. Following is an example of orElseGet() method:

 char result = Stream.of('a', 'b', 'c')
.filter(c -> Character.isDigit(c))
.findFirst()
.orElseGet(()->'0');
System.out.println(result);
 0

(3) Optional.stream()

This new method returns a Stream containing only one element returned by this Optional. If the value is not present then an empty Stream is return:

 OptionalInt opt1 = IntStream.of(2, 5, 6).max();
OptionalInt opt2 = IntStream.of(1, 3, 7).max();
IntStream.concat(opt1.stream(), opt2.stream())
.forEach(System.out::println);
 6
 7

See Also