Java
optional
java8
Java9

JavaのOptionalで値存在時/非存在時の処理を書く際の指針

JavaのOptionalで値存在時/非存在時の処理を書く際、以下の3つのメソッドを使用することができます。

  • Optional.isPresent()
  • Optional.ifPresent()
  • Optional.ifPresentOrElse()(※Java 9以降)

どういう場合にどのメソッドを使うべきか、僕なりの指針を考えてみました。

各メソッドの仕様

Optional.isPresent()

Optional.isPresent()は、値が存在する場合はtrue、存在しない場合はfalseを返すメソッドです。
if~else文と組み合わせて使うことで、従来のnullチェックの構文をほぼそのまま置き換えることができます。
もっとも、そのような使い方は「ただnullチェックを置き換えただけで、Optionalを使う意味がない」とも言われています。

Optional<String> foo = Optional.ofNullable("foo");

if(foo.isPresent()){
    System.out.println("foo=" + foo.orElse(""));
}else{
    System.out.println("foo is null");
}

Optional.ifPresent()

Optional.ifPresent()は、値が存在する場合は引数で指定した関数(Consumer)を実行するメソッドです。
値が存在しない場合の処理を記述できず、関数内でブロック外の変数を書き換えられないという制約があります。

Optional<String> foo = Optional.ofNullable("foo");

foo.ifPresent(f -> System.out.println("foo=" + f));

Optional.ifPresentOrElse()

Optional.ifPresentOrElse()は、値が存在する場合は引数で指定した1個目の関数(Consumer)を実行し、存在しない場合は引数で指定した2個目の関数(Runnable)を実行するメソッドです。
値が存在しない場合の処理を記述できますが、関数内でブロック外の変数を書き換えられないという制約があります。
Java 9で追加されました。

Optional<String> foo = Optional.ofNullable("foo");

foo.ifPresentOrElse(f -> System.out.println("foo=" + f), () -> System.out.println("foo is null"));

フローチャート

どういう場合にどのメソッドを使うべきかのフローチャートです。

フローチャート

基本的にはOptional.ifPresent()を使用し、ブロック外の変数を書き換えたい場合や、値が存在しない場合の処理を記述したい場合のみ他のメソッドを使うのがよさそうです。

余談

JavaのOptionalクラスをもとに僕がつくったJavaScriptライブラリOptional.jsでは、Optional.ifPresent()を終端操作ではなく中間操作としたうえで、それとは別にOptional.ifAbsent()を定義することで、以下のようにメソッドチェーンで値が存在する場合の処理と存在しない場合の処理を記述できるようにしています。

const absentableValue = Optional.ofAbsentable('foo');
absentableValue 
    .ifPresent(v => console.log('name=' + v))
    .ifAbsent(() => console.log('name is null or undefined'));

参考リンク