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-2015-004-1

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

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

記事を読む

icatch-sublimetext_9222613858_mini-thumbnail

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

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

記事を読む

icatch-pray_c916c87577_mini-thumbnail

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

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

記事を読む

icatch-medium_4301351732-resized

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

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

記事を読む

icatch-vagrant_box_customize

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

配布されている Vagrant の Box ファイルを使って検証環境を構築することが多くなってきた。

記事を読む

icatch-8442052993_2978189f52_z-resized

参照可能な yum リポジトリを確認する yum コマンドとワンライナー

あるパッケージをインストールするために配布リポジトリの設定を追加することがあります。 ビジネスユー

記事を読む

icatch_3304032405-resized

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

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

記事を読む

icatch_5623339500-resized

Bundler を使ってプロジェクト用の Gem をインストールして Gemfile をバージョン管理ツールに登録するまでの流れ

Bundler を使い始める人向けにまとめた次の記事を書きました。 CentOSにRubyのBu

記事を読む

icatch-2015-006-1

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

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

記事を読む

icatch-vacuum_9060011568_mini-thumbnail

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

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

記事を読む

Googleアドセンス用(PC)

Message

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


+ 五 = 9

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