0
0

More than 3 years have passed since last update.

【StreamAPI】max(またはmin)で空Optionalが返るシチュエーション

Last updated at Posted at 2019-12-22

maxの返り値はOptional型

Streamのメソッドにmax(以下、minも同様)というものがある。一見、Streamの最大値をそのまま返すように見えるが、返り値の型は以下の例の通りOptionalである。

コード


    List<Integer> integerList = Arrays.asList(1, 2, 3);
    Optional<Integer> maxIntegerOpt = integerList
            .stream()
            .max(Integer::compareTo);

    System.out.println("maxIntegerOpt = " + maxIntegerOpt);

実行結果

maxIntegerOpt = Optional[3]

ということは最大値が見つからない場合もあるということである。

色んな値のStreamで試してみた

「え、最大値が見つからないことってあるの?」と疑問に思ったので、色んな値のStreamで試してみた。

重複する値がある場合は見つかる

ははーん、きっと値が重複してたら最大値が一意に定まらないから最大値なしとなるんだな!
コード

    List<Integer> integerList = Arrays.asList(1, 2, 3, 3);
    Optional<Integer> maxIntegerOpt = integerList
            .stream()
            .max(Integer::compareTo);

    System.out.println("maxIntegerOpt = " + maxIntegerOpt);

実行結果

maxIntegerOpt = Optional[3]

げぇー!重複してるのは一つの値としてまとめて判定している!地味にこれは新たな発見。

Streamが空の場合は見つからない

正解はこちら。
コード


    List<Integer> integerList = Collections.emptyList();
    Optional<Integer> maxIntegerOpt = integerList
            .stream()
            .max(Integer::compareTo);

    System.out.println("maxIntegerOpt = " + maxIntegerOpt);

実行結果

maxIntegerOpt = Optional.empty

まあ要素が無ければ最大値も調べようがないですよね。てか公式に書いてました。マニュアル読めって話。

Streamが空になるシチュエーション

※コメントを受けて追記しました。
空Streamに対して最大値を取りに行くシチュエーションある?と思っていましたが、間にfilterなどを噛ます場合は途中でStreamが空になります。
例えば以下のような、100以下の値でfilterをかけて最大値を取りに行く場合は途中でStreamが空になり、空Optionalが返ります。

コード


    List<Integer> integerList = Arrays.asList(101, 104);
    Optional<Integer> maxIntegerOpt = integerList
            .stream()
            .filter(integer -> integer <= 100)
            .max(Integer::compareTo)

この場合、結果が空Optionalということはfilterに該当する要素がなかったということなので、結果を利用する側でその場合の処理を書く必要があります(そのためのOptional)。

空Optionalを返すのってどうよ?

要するにmaxはStreamが空でもエラーとせず、空Optionalを返してくれます。
しかし直感的にその動作がわかるでしょうか?最大値を調べようがなく、自分はてっきり何か例外が返ってくるものだと思っていましたので、空Optionalが返ってくることに違和感を感じていました。

※ご指摘いただき、Optionalで返すことで、空Streamでも例外とならないことが明らかだと判断しました。

0
0
7

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0