[Java] 今さら聞けない Optional その3

Optional 3回目です。1回目 2回目

今回は

  • orElse
  • orElseGet
  • orElseThrow

について勉強しました。

orElse

Optional が値を持っている場合はその値を、空の場合は渡された値を返します。

Optional<String> opt = Optional.of("non-null");
System.out.println(opt.orElse("null"));

// non-null
Optional<String> opt = Optional.empty();
System.out.println(opt.orElse("null"));

// null

前回のまとめ言ってたこの例ですが、

String s = opt.isPresent() ? opt.get() : "default text";

orElse を使うとこう書けます。

String s = opt.orElse("default text");

orElseGet

Optional が値を持っている場合はその値を返します。空の場合は渡されたコードブロックを実行し、コードブロックが返した値を返します。

Optional<String> opt = Optional.of("non-null");
System.out.println(opt.orElseGet(() -> "null"));

// non-null
Optional<String> opt = Optional.empty();
System.out.println(opt.orElseGet(() -> "null"));

// null

orElseThrow

Optional が値を持っている場合はその値を返します。空の場合は例外を返すコードブロックを実行し、例外を Throw します。

Optional<String> opt = Optional.of("non-null");
System.out.println(opt.orElseThrow(java.lang.IndexOutOfBoundsException::new));

// non-null
Optional<String> opt = Optional.empty();
System.out.println(opt.orElseThrow(java.lang.IndexOutOfBoundsException::new));

// Exception in thread "main" java.lang.IndexOutOfBoundsException

orElse と orElseGet の違い

上記のように、orElse は引数をそのまま返しのに対して orElseGet はコードブロックが返す値を返します。orElse だけで良くない?と思うかもしれませんが、orElseGet には次のような利点があります。

それは、「コードブロックは Optional が空の場合しか実行されない」点です。

import java.util.Optional;

public class Test {
    public static void main(String[] args) {
        Optional<String> opt = Optional.of("non-null");
        String v = opt.orElseGet(() -> {
            // このコードブロックは実行されない。
            fn1();
            return "default value";
        });
        System.out.println(v);
    }

    private static void fn1() {
        System.out.println("fn1 start.");
    }
}

// non-null

コードブロックでラップするため、empty 時に返す値の取得を遅延評価できます。キャッシュがあればそれを使うけどない場合は DB から取得する、というようなケースに便利そうです。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です