A review note for the class java.util.Optional

Overview

This is a review note of the java.util.Optional class introduced in Java 1.8.

environment

reference

Optional<T> - Java 1.8

empty / of / ofNullable

Both are static methods. Optional does not have a public constructor, so use these methods to create an Optional object.

empty

Returns an Optional object with a null value.

Optional<String> empty = Optional.empty();
empty.isPresent();
// false

empty.orElse("other");
// other

empty.get();
// java.util.NoSuchElementException: No value present

of

Returns an Optional object with a non-null value.

String str = "nonNull";
Optional<String> nonNullString = Optional.of(str);
nonNullString.isPresent();
// true

nonNullString.get();
// result : nonNull

Passing a null object to of throws an exception.

String str = null;
Optional.of(str);
//  java.lang.NullPointerException

ofNullable

Returns an Optional object with a value that may be null (nullable).

String str = null;
Optional<String> nullableString = Optional.ofNullable(str);
nullableString.isPresent();
// false

nullableString.orElse("other");
// other

get / isPresent

get

Returns the value held by the Optional object. If the value to be retained is null, NoSuchElementException will be thrown.

String str = "apple";
Optional<String> nullableString = Optional.ofNullable(str);

nullableString.get();
// apple
String str = null;
Optional<String> nullableString = Optional.ofNullable(str);

nullableString.get();
// java.util.NoSuchElementException: No value present

isPresent

Returns true if the value held by the Optional object is non-null, false if it is null.

String str = "apple";
Optional<String> nullableString = Optional.ofNullable(str);

nullableString.isPresent();
// true
String str = null;
Optional<String> nullableString = Optional.ofNullable(str);

nullableString.isPresent();
// false

orElse / orElseGet / orElseThrow

orElse

Returns the value held by the Optional object. If the value to be retained is null, the specified value is returned. (Null is also possible)

String str = "nonNull";
Optional<String> nullableString = Optional.ofNullable(str);

nullableString.orElse("other");
// nonNull
String str = null;
Optional<String> nullableString = Optional.ofNullable(str);

nullableString.orElse("other");
// other

nullableString.orElse(null);
// null

orElseGet

Returns the value held by the Optional object. If the value to be retained is null, the result of the specified Supplier is returned. If Supplier returns null, it will return null.

String str = "nonNull";
Optional<String> nullableString = Optional.ofNullable(str);

nullableString.orElseGet(() -> "other");
// nonNull
String str = null;
Optional<String> nullableString = Optional.ofNullable(str);

nullableString.orElseGet(() -> "other");
// other

nullableString.orElseGet(() -> null);
// null

orElseThrow

Returns the value held by the Optional object. If the value to be retained is null, the specified exception will be thrown.

String str = null;
Optional<String> nullableString = Optional.ofNullable(str);

nullableString.orElseThrow(RuntimeException::new);
// java.lang.RuntimeException

ifPresent

If the value held by the Optional object is non-null, the Consumer processing block specified in the argument is executed with that value. If the value held by the Optional object is null, no exception will be thrown and nothing will be executed.

Optional<Employee> employee = Optional.ofNullable(new Employee(1L, "john"));
employee.ifPresent((e) -> {
    e.setName(e.getName().toUpperCase());
    System.out.println(e);
    // Employee{id=1, name='JOHN'}
});

filter / map / flatMap

filter

If the value held by the Optional object is non-null, the Predicate processing block specified in the argument with that value is executed.

Optional<String> nullableString = Optional.ofNullable("banana");

Optional<String> filtering = nullableString.filter(str -> str.length() > 5);
filtering.isPresent();
// true

filtering.orElse("other");
// banana

If the value held by the Optional object is null, or if the Predicate processing block returns false, an empty Optional is returned.

Optional<String> nullableString = Optional.ofNullable("apple");
// Optional<String> nullableString = Optional.ofNullable(null);

Optional<String> filtering = nullableString.filter(str -> str.length() > 5);
filtering.isPresent();
// false

filtering.orElse("other");
// other

map

If the value held by the Optional object is non-null, the processing block of the Function specified in the argument is executed with that value.

Optional<String> nullableString = Optional.ofNullable("apple");
Optional<Integer> mapping = nullableString.map(str -> str.length());

mapping.isPresent();
// true

mapping.orElse(0);
// 5

If the value held by the Optional object is null, or if the processing block of the Function returns null, an empty Optional is returned.

Optional<String> nullableString = Optional.ofNullable(null);
Optional<Integer> mapping = nullableString.map(str -> str.length());

mapping.isPresent();
// false

mapping.orElse(0);
// 0

flatMap

If the value held by the Optional object is non-null, the processing block of the Function specified in the argument is executed with that value. The difference from map is that Function returns an Optional object.

The Function specified in map takes T type and returns U type.

Function<? super T,? extends U> mapper

The Function specified in flatMap takes T type and returns Optional type.

Function<? super T,Optional<U>> mapper
Optional<Long> optId = Optional.of(1L);
Optional<String> optName = Optional.of("john");

Optional<Employee> result = optId.flatMap(id -> optName.flatMap(name -> Optional.of(new Employee(id, name))));

result.isPresent();
// true

result.orElse(null);
// Employee{id=1, name='john'}

If the value held by the Optional object is null, an empty Optional is returned.

Optional<Long> optId = Optional.of(1L);
Optional<String> optName = Optional.ofNullable(null);

Optional<Employee> result = optId.flatMap(id -> optName.flatMap(name -> Optional.of(new Employee(id, name))));

result.isPresent();
// false

result.orElse(null);
// null

If you use a Function that returns Optional in map, the return value will be an unexpected type.

Optional<Optional<String>> nullableName = employee.map(emp -> Optional.ofNullable(emp.getName()));

API added in Java 9

ifPresentOrElse

There are more variations of ifPresent. If the value held by the Optional object is null, the Runnable processing block specified in the argument is executed.

Optional<Employee> employee = Optional.ofNullable(null);

employee.ifPresentOrElse((e) -> {
    e.setName(e.getName().toUpperCase());
    System.out.println(e);
},
() -> {
    System.out.println("empty action");
    // empty action
});

or

If the value held by the Optional object is null, the Optional object generated by the Supplier specified in the argument is returned. An exception will be thrown if the Supplier returns null.

String str = null;
Optional<String> nonNullString = Optional.ofNullable(str).or(() -> Optional.of("nonNull"));

nonNullString.isPresent();
// true

nonNullString.get();
// nonNull

stream

If the value held by the Optional object is non-null, a stream with only that value is returned, and if it is null, an empty stream is returned.

List<Optional<String>> list = List.of(
    Optional.of("a"),
    Optional.of("b"),
    Optional.of("c"),
    Optional.empty(),
    Optional.of("e"),
    Optional.empty(),
    Optional.of("g")
);

list.stream().filter(Optional::isPresent).map(Optional::get).forEach(System.out::println);
// a
// b
// c
// e
// g

//When using stream
list.stream().flatMap(Optional::stream).forEach(System.out::println);
// a
// b
// c
// e
// g

API added in Java 10

  • Module: java.base
  • Package: java.util

orElseThrow

Returns the value held by the Optional object. Throws NoSuchElementException if the value to keep is null. This behavior is the same as the get method. For this reason, rather than adding a variation of orElseThrow with the same method name from Java 1.8

java1.8_orElseThrow signature


public <X extends Throwable> T orElseThrow​(Supplier<? extends X> exceptionSupplier)
    throws X extends Throwable

It feels like a method that replaces the get method, which removes ambiguity from the get method name.

java1.8_get signature


public T get()

You can see that orElseThrow can throw an exception from the method name.

java10_orElseThrow signature


public T orElseThrow()

API added in Java 11

isEmpty

java11_isEmpty signature


public boolean isEmpty()

Returns true if the value does not exist.

API added in Java 12

No API has been added.

API added in Java 13

No API has been added.

API added in Java 14

No API has been added.

Other review notes

Recommended Posts

A review note for the class java.util.Optional
A review note for the class java.util.Scanner
A review note for the class java.util.Objects
A review note for the package java.time.temporal
A note on the libGDX Utils class
A note about the scope
A note for Initializing Fields in the Java tutorial
A review note of the Spring Framework Resource interface
A murmur about the utility class
A rudimentary note on the Fibonacci sequence
A note for those who live with JMockit
A note when the heroku command becomes unavailable
A quick review of Java learned in class
A note about the Rails and Vue process
Addressing the issue of slow random access for linkedList, a collection type class
[For beginners] Where to review when a class cannot be found at compile time
A review of the code used by rails beginners
I made a check tool for the release module
What is the difference between a class and a struct? ?? ??
A quick review of Java learned in class part4
I read the readable code, so make a note
[Ruby / Rails] Set a unique (unique) value in the class
A quick review of Java learned in class part3
A quick review of Java learned in class part2
How to make a mod for Slay the Spire
About the StringBuilder class
Note No. 6 "Calculate the formula for the one-digit sum difference received as a character string" [Java]
Java inner class review
Nested class (for myself)
SDWebImage: How to clear the cache for a particular UIImageView
Rails: I've summarized the model and database for a moment.
A note about the seed function of Ruby on Rails
I tried JAX-RS and made a note of the procedure
I want to give a class name to the select attribute
I investigated Randoop, a JUnit test class generator for Java
A memorandum to reach the itchy place for Java Gold
Aiming for a basic understanding of the flow of recursive processing
A 25-day review and future efforts for NRI OpenStandia's Keycloak
With the software I've been making for a long time ...
Modeling a Digimon with DDD for the first time Part 1