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-9214710040_822a4c3456_z-resized

ロードアベレージを監視するシェルスクリプトを作成してみた

このブログを運用している Linux サーバの負荷が高い状態になってました。 何か被害にあったとかで

記事を読む

icatch-medium_4301351732-resized

mp3splt を実行して “undefined symbol: mp3splt_u_check_if_directory” と出力されたときの対処法

mp3 ファイルを分割してくれる mp3splt というライブラリがあります。 mp3 ファイルを

記事を読む

no image

GoogleGuavaのRangeを使って範囲判定を簡潔に書く

次のような判定処理を if 文で書くことがよくある。 もし 100 よりも大きければ(=大小判定

記事を読む

no image

より安全にパスワードを保存するために考えること

知ってる人にとっては当たり前のことだろうが、あまり深く考えたことがなかったので調べてみた。 前提

記事を読む

icatch-8587724648_24926df337_z-resized

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

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

記事を読む

no image

IE9 のキャッシュ対策

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

記事を読む

icatch_3304032405-resized

CentOS に yum-plugin-priorities プラグインをインストールする

yum を使ってあるパッケージをインストールしようと調べていたところ、yum-plugin-prio

記事を読む

icatch-sublimetext_9222613858_mini-thumbnail

Sublime Text3 のインストール直後に行った設定メモ

突発的に自宅のマシンにインストールしてあった Sublime Text2 を 3 にアップデートしま

記事を読む

icatch-markdown_6281167385_mini-thumbnail

Sublime Text3 で Markdown のシンタックスハイライトを有効にする手順

IT 関連の職場であれば、部署やチーム単位に Redmine とか Backlog を使って TOD

記事を読む

no image

no space left と表示されたときの対処法

タイトルの "no space left" とは「書き込みたいけど、ディスクの飽

記事を読む

Googleアドセンス用(PC)

Message

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


− 2 = 五

次の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 ↑