Java基礎ーOptional

java.util.Optionalクラス

Optionalは値をラップし、その値がnullかもしれないことを表現するクラス。
Optionalオブジェクトの生成

メソッド 説明
Optional empty() null値を持つOptionalオブジェクトを返す
Optional of() 非null値を持つOptionalオブジェクトを返す
Optional ofNullable() nullかもしれない値を持つOptionalオブジェクトを返す

Optionalオブジェクトの生成例

Optional<String> empty = Optional.empty();

String str = "notNull";
Optional<String> notNull = Optional.of(str); //nullなオブジェクトを渡すとNullPointerExceptionが発生

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

主なメソッド

メソッド 説明
T get() Optionalオブジェクトが保持する値を返す
boolean isPresent() Optionalオブジェクトが保持する値が非nullの場合はtrueを返す
T orElse(T other) Optionalオブジェクトが保持する値を返す。保持する値がnullの場合は指定した値を返す
T orElseGet(Supplier<? extends T> supplier) Optionalオブジェクトが保持する値を返す。保持する値がnullの場合は指定したSupplierの結果を返す
T orElseThrow(Supplier<? extends X> supplier) Optionalオブジェクトが保持する値を返す。保持する値がnullの場合は指定した例外がスローされる
void ifPresent(Consumer<? super T> action) Optionalオブジェクトが保持する値が非nullの場合、引数に指定するConsumerの処理ブロックを実行する
Optional<T> filter(Predicate<? super T> predicate) Optionalオブジェクトが保持する値が非nullの場合、引数に指定するPredicateの処理ブロックを実行する
Optional<U> map(Function<? super T, ? extends U> mapper) Optionalオブジェクトが保持する値が非nullの場合、引数に指定するFunctionの処理ブロックを実行する
void ifPresentOrElse(Consumer action, Runnable emptyAction) nullの場合と非nullの場合それぞれ指定した処理を行う
Optional<T> or(Supplier supplier) nullの場合のみ処理を実行する
stream() Optional型のオブジェクトからnullでないものだけを取り出す
T orElseThrow() nullの場合はNoSuchElementExceptionをスロー。nullでない場合は値を返す
boolean isEmpty() Optionalオブジェクトが保持する値がnullの場合はtrueを返す

メソッド使用例

String str = "apple";
Optional<String> nullable = Optional.ofNullable(str);
String s = null;
Optional<String> nullVal = Optional.ofNullable(s);

// getメソッド
nullable.get(); // apple

// isPresentメソッド
nullable.isPresent(); //true
nullVal.isPresent(); // false

// orElseメソッド
nullable.orElse("other"); //apple
nullVal.orElse("other"); // other

// orElseGetメソッド
nullable.orElseGet(() -> "other"); //apple
nullVal.orElseGet(() -> "other"); // other
nullVal.orElseGet(() -> null); // null

// orElseThrowメソッド
nullable.orElseThrow(RuntimeException::new); //apple
nullVal.orElseThrow(RuntimeException::new); // RuntimeException

// ifPresentメソッド
nullable.ifPresent((e) -> {
        System.out.println(e.toUpperCase()); // APPLE
});
nullVal.ifPresent((e) -> {
        System.out.println(e.toUpperCase()); // 実行されない
});

// filterメソッド
Optional<String> filter = nullable.filter(val -> val.length() > 5);
filter.isPresent(); // true
Optional<String> filter = nullVal.filter(val -> val.length() > 5); //nullの場合は空のOptionalが返される
filter.isPresent(); // false

// mapメソッド
Optional<Integer> mapping = nullable.map(val -> val.length());
mapping.isPresent(); // true
Optional<Integer> mapping = nullVal.map(val -> val.length()); //nullの場合は空のOptionalが返される
mapping.isPresent(); // false

// ifPresentOrElseメソッド
nullable.ifPresentOrElse((e) -> {
    System.out.println(e.toUpperCase());
}, () -> {
    System.out.println("null!!"); // 実行されない
});

// ifPresentOrElseメソッド
nullVal.ifPresentOrElse((e) -> {
    System.out.println(e.toUpperCase()); // 実行されない
}, () -> {
System.out.println("null!!");
});

// orメソッド
System.out.println(nullVal.or(() -> Optional.of("null!!!!!")).get());

List<String> list1 = List.of("banana", "melon");
List<String> list2 = null;

Optional<List<String>> value1 = Optional.ofNullable(list1);
Optional<List<String>> value2 = Optional.ofNullable(list2);

// streamメソッド
value1.stream().flatMap(x -> x.stream()).forEach(System.out::println);
value2.stream().flatMap(x -> x.stream()).forEach(System.out::println);

// orElseThrowメソッド
nullable.orElseThrow(); // apple
nullVal.orElseThrow(); // NoSuchElementException

// isEmptyメソッド
nullVal.isEmpty(); // true
nullable.isEmpty(); // false