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-003-1

Vagrantで起動したCentOS上のMySQLにホストOSからログインする設定

マシンを新しくしたこともあり、検証と称してソフトウェアをやみくもにインストールすることに抵抗が出てき

記事を読む

no image

VPS に Redmine を設置したときに対処したトラブル

Redmine のインストール自体は Redmine 2.3をCentOS 6.4にインストールする

記事を読む

icatch-_9692711856-resized

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

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

記事を読む

icatch-markdown_6281167385_mini-thumbnail

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

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

記事を読む

icatch_2385618390-resized

Linuxでmp3をお手軽に結合する

このブログを運用している Linux サーバで radiko.jp から番組を mp3 に録音して個

記事を読む

icatch-jersey_multi_pathparams

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

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

記事を読む

icatch_5623339500-resized

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

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

記事を読む

no image

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

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

記事を読む

no image

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

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

記事を読む

icatch-2015-004-1

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

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

記事を読む

Googleアドセンス用(PC)

Message

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


+ 5 = 六

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