プログラミング Java

【Java】Optionalとは何か?どのように使うのか?

投稿日:2023年5月17日 更新日:

Optionalとは?

JavaのOptionalクラスは、値がnullである可能性がある場合に値をラップするためのクラスです。
例えば、Mapから値を取得する際に値が存在しない場合、値はnullになります。
Optionalクラスを使用すると、値がnullかどうかを簡単に確認し、nullの場合はデフォルト値を設定できます。

つまりOptionalクラスを使うと、値がnullである可能性のあるコードを安全に扱うことができるようになります。

Java8から使用できるようになっているので、執筆時点においてはほとんどの開発環境で利用可能になっているはずです。

どういった場合に使うのか?

Optionalクラスは、値がnullである可能性のあるメソッドの戻り値としてよく使用されます。

例えば、Mapから値を取得するメソッドを作成する場合、そのメソッドの戻り値をOptional型にします。
これにより、呼び出し側は値がnullかどうかを簡単に確認し、nullの場合はデフォルト値を設定できるようになります。

使い方

Optionalクラスには、map、flatMap、filterなど、さまざまなメソッドが用意されており、これらのメソッドを使用して、Optionalオブジェクトを操作して値を変更できます。
例えば、Optionalオブジェクトにmapメソッドを適用すると、Optionalオブジェクトの値が指定された関数でマップされます。

しかし主な使い方は以下になることが多いでしょう。

Optionalを生成する

Optionalを使用するには、まずOptionalオブジェクトを作成する必要があります。
Optionalオブジェクトを作成するには、ofNullable()メソッド、またはof()メソッドを使用します。

ofNullable()メソッドは、値とnullを受け入れます。
値がnullでない場合は、Optionalオブジェクトが作成されます。
値がnullの場合は、空のOptionalオブジェクトが作成されます。

of()メソッドはnullではない値のみを受け入れ、Optionalオブジェクトを作成します。
もし、nullをof()メソッドで生成しようとした場合、NullPointerExceptionがスローされるので注意が必要です。

定数をOptionalに格納する場合はof()メソッドで問題ありませんが、多くの場合は変数を格納することになるでしょう。
変数はnullである可能性があるため、特に理由が無い限りはofNullable()メソッドを使用してOptionalオブジェクトを生成するようにして下さい。

Nullであるか判定する

Optionalオブジェクトが作成されたら、isPresent()メソッドを使用して値が存在するかどうかを確認できます。
isPresent()メソッドがtrueを返す場合、値は存在します。isPresent()メソッドがfalseを返す場合、値は存在しません。

値が存在しないことを確認したい場合は、isEmpty()メソッドを使うこともできます。
isEmpty()メソッドがtrueを返す場合、値は存在しません。falseを返す場合、値は存在します。

値を取得する

値が存在する場合は、get()メソッドを使用して値を取得できます。
通常、get()メソッドを実行する前にisPresent()メソッドで値が存在するかの確認を行うべきです。

もし存在しない値をget()しようとするとNoSuchElementExceptionがスローされるので注意が必要です。

使用例は「Nullであるか判定する」のisPresent()メソッドのコードを参照して下さい。

デフォルト値を返す

値が存在しない場合、orElse()メソッドまたはorElseGet()メソッドを使用してデフォルト値を取得できます。

orElse()メソッドはOptionalオブジェクトが空でない場合は、Optionalオブジェクトの値が返されます。
Optionalオブジェクトが空の場合、デフォルト値が返されます。デフォルト値にはnullを与えることもできます。

orElseGet()メソッドはOptionalオブジェクトが空でない場合は、Optionalオブジェクトの値が返されます。
Optionalオブジェクトが空の場合、Supplierの実行結果が返されます。

Collection.stream()での使用例

ListやSetといったCollectionからstreamを使って任意の値を取得する以下のメソッドはOptionalを返すようになっています。

  • findFirst()
  • findAny()
  • max()
  • min()
  • reduce()
  •  
    以下のように、任意のリストのうち最初の文字が”h”である最初の値を取得するとします。

    この例では”hoge”が該当するので値が取得されて表示されますが、該当する値が無ければ何も表示されません。
    このようにCollection.streamの操作においてOptionalは押さえて置くべき技術です。

    値がある場合だけ実行する

    Optionalには値がある場合だけ、処理をさせることができるifPresent()メソッドがあります。

    「Collection.stream()での使用例」の(1)を参照して下さい。
    ここでは値がある場合はコンソールに出力され、もし値が無ければ処理は実行されません。

    また、(1)は以下のコードと同等なので、if文を使わないことでより簡潔に書けるようになっています。

    まとめ

    • OptionalはNullを安全に扱うためのクラスである。
    • Optionalから値を取得する前にNullでないことを確認すべきである。
    • Nullである場合にデフォルト値を返す仕組みが用意されている。
    • ifPresent()メソッドを使うと分岐を簡潔に記述することができる。

    Optionalを初めて使う場合、ちょっとした抵抗や違和感があるかもしれません。
    しかし、Optionalを使うことでNullへの安全性が向上するはずです。
    今後も利用される場面は増えていくと思いますので、しっかり使えるようになっておきたい技術です。

    参考

    【公式API】Java11 クラスOptional<T>
    【公式API】インタフェースStream

     
    最後までお読み頂き、ありがとうございました!
    ご意見・ご要望がありましたら、遠慮なくコメント下さい!
    もし内容が良かったらランキング評価を頂けると励みになります(^^)

    ランキング評価する

    -プログラミング, Java
    -, , ,

    執筆者:


    comment

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

    CAPTCHA


    関連記事

    【Java】配列の扱い方(初期化、追加、ソート、List変換など)

    配列とは? ザックリ言うと、同じ種類の複数データを1つの変数に持つことができる仕組みです。 でも文字だけだとわかりずらいですよね💦 なので以下のコードを確認してみて下さい。 [crayon-64766 …

    【SpringSecurity】#2~ ユーザ毎の権限設定(認可)

    概要 権限によって、アクセス可能なページを制限する機能の実装します。 管理者画面を作成し、権限によって画面の出し分けを行います。 前提 #1~ ログイン画面の実装が完了していること。 管理者画面の追加 …

    Jacksonで日付がずれる場合、Timezone設定を直す

    現象 JacksonでCSV出力する際、日付がズレて出力される。   原因 タイムゾーンの設定がTokyo/Asiaになっていない。   対策 application.proper …

    【Java入門】クラスの継承、オーバーライド

    概要 クラスの継承とは、継承元(親)のフィールド(値)、メソッド(機能)を継承先(子)に引き継がせることです。 継承先(子)では、追加のフィールド(値)、メソッド(機能)を持つことができます。 つまり …

    【SpringBoot入門】#3~ Index画面の作成

    このチュートリアルでは、簡易な書籍管理システムを作っていきます。 まず最初にIndex画面を作成していきます。 HTML作成 以下の配下にindex.htmlを作成します。 配置先:プロジェクト(ここ …

    ■運営者プロフィール
    IT業界10年のエンジニア。
    PHP -> VBA -> Javaと渡り歩いてきて、今はJavaをメインにフリーランスエンジニアとして活躍中!

    [保有資格]
    ・Java SE 11 Gold

    一度はエンジニアを辞めざるを得なかった私が再びエンジニアとして復活した数奇な物語

    SpringFramworkの良書

    ■おすすめ教材
    Javaの基本を学んだ人が、次のステップとして読む本(中級者向け)

    ※SpringはJavaのFrameworkの1つです。
    変更のしやすさ、保守性の高さが特徴です。