Optionalから値を取り出すにはorElseGet()を使う

公開日: : 最終更新日:2015/10/19 プログラム

Optional が値を持っていない場合のみ ◯◯ を実行する」を実装するときは Optional#orElseGet() を使う、という教訓のメモ。

Optional#orElseGet() とすべきところを Optional#orElse() で実装していたので、意図せぬバグを発生させるところだった。
簡単な例を使って Optional#orElseGet()Optional#orElse() の動きの違いを確認しておく。

icatch-2015-002

目次

1. Optional#orElseGet() を使った場合

簡単な例として、Optional#of("hoge") でインスタンスを生成し、orElseGet() を実行してみる。

Optional.of("hoge").orElseGet(() -> {
    log.info("-> Supplier_hoge"); // このログは出力されない
    return "fuga";
});

生成した Optional は “hoge” を持っているため orElseGet() は実行されない。
ラムダ式内に定義したログは出力されないことからそれが分かる。

では、Optional#empty() としてみる。

Optional.empty().orElseGet(() -> {
    log.info("-> Supplier_empty"); // このログは出力される
    return "fuga";
});

こちらは値を持っていないため orElseGet() が実行される。
ラムダ式内に定義したログが出力されることからもそれが確認できる。

2. Optional#orElse() を使った場合

上記と同様に Optional#of("hoge") でインスタンスを生成し、orElse() を実行してみる。

Optional.of("hoge").orElse(getDefault());

private static String getDefault() {
    log.info("-> getDefault"); // このログは出力される
    return "fuga";
}

生成した Optional は “hoge” を持っているにも関わらず orElse() が実行される。
getDefault() 内に定義したログが出力されることからそれが確認できる。

Opitonal が値を持っている場合 orElse() は実行してほしくないケースがほとんどだと思われるので、orElse() を使う場合は処理内容に気をつけたほうが良さそうだ。
特に、副作用が発生する処理を書いてしまうと、どこでそれが発生したのか見失うことになりかねない。個人的に要注意。

3. まとめ

  • Optional が値を持っていない場合のみ ◯◯ を実行する」を実装するときは Optional#orElseGet() を使う
    • 思い切って Optional#orElse() の使用はやめてみる
  • ラムダ式を使えば、必要になったタイミングで初めて計算されるので処理効率が上がる
    • もっと積極的にラムダ式を使ってみる

4. 更新履歴

  • 2015/10/10: 初版作成
  • 2015/10/19: 内容を編集

Googleアドセンス用(PC)

  • このエントリーをはてなブックマークに追加
  • follow us in feedly

関連記事

icatch-jersey_multi_pathparams

Jerseyの@PathParamはスラッシュの間に複数指定できる

http://hoge-api/user/{id}.{format} のような URL も以下のよう

記事を読む

no image

IE9 のキャッシュ対策

どのようなバグだったのか POST で送信した内容を確認する画面で、最新の内容が表示されないという

記事を読む

icatch-vacuum_9060011568_mini-thumbnail

GitHub にアップされているブランチをローカルに取り込む

GitHub に限らず、会社や自分で Git のサーバを使った場合にも当てはまりますが、毎回同じこと

記事を読む

icatch-2015-006-1

バリデーションチェックにJava8のOptionalを使ってスマートに書く(自分比)

Web アプリのバリデーションチェックにアノテーションを使うことが増えた。だが、アノテーションで実装

記事を読む

icatch_442682895-resized

scp コマンドを yum を使って CentOS にインストールする

小ネタです。 yum install scp ではなかったのでメモしておきます。 photo

記事を読む

icatch-markdown_14bd207bd7_mini-thumbnail

Markdown記法のテキストに書いたソースコードをシンタックスハイライトするプラグイン

SublimeText3 で拡張子が md のファイルを開いたときに、文章中に書かれたプログラムのソ

記事を読む

icatch-_9692711856-resized

シェルスクリプトでメールを送信する

このブログを運用している Linux サーバの監視スクリプトを作成した記事を書きました。 ロード

記事を読む

icatch-pray_c916c87577_mini-thumbnail

Eclipse がエラーメッセージを出力して起動しなくなった場合の対処法

Eclipse の exe ファイルをクリックすると(または、実行すると)、 Eclipse のスプ

記事を読む

icatch-2015-004-1

Vagrantで起動したCentOS上のOctopressをホストOSから確認する設定

タイトルの通りだが、Vagrant を使って起動した CentOS に Octopress をインス

記事を読む

icatch-8587724648_24926df337_z-resized

yum のリポジトリ ATrpms を参照できるように設定する

あるツールの動作検証をしようと調べたところ、そのツールは ATrpms リポジトリが提供しているとの

記事を読む

Googleアドセンス用(PC)

Message

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


4 − = 二

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Googleアドセンス用(PC)

icatch-jersey_multi_pathparams
Jerseyの@PathParamはスラッシュの間に複数指定できる

http://hoge-api/user/{id}.{format}

icatch-vagrant_box_customize
VagrantのBoxファイルをカスタマイズして独自のBoxファイルを作成する

配布されている Vagrant の Box ファイルを使って検証環境を

icatch-2015-006-1
バリデーションチェックにJava8のOptionalを使ってスマートに書く(自分比)

Web アプリのバリデーションチェックにアノテーションを使うことが増え

icatch-2015-005-1
ユニットテストの偏りを防ぐ命名規則の付け方

ユニットテスト名に以下の命名規則を付けるようにして二ヶ月ぐらい経った。

icatch-2015-004-1
Vagrantで起動したCentOS上のOctopressをホストOSから確認する設定

タイトルの通りだが、Vagrant を使って起動した CentOS に

→もっと見る

PAGE TOP ↑