Optionalについて調べてみた その4

【前提条件】

[環境]
[参考資料]

Java8 APIドキュメント
Java Platform SE 8

【概要】

今回はOptionalからmap/filterメソッドを使ってみます。

Stream APIと同じく
mapは値を変換するメソッドで
filterは条件にマッチする場合にのみ値を取得するメソッドです。

【mapメソッド】

まずはmapメソッドから見ていきます。

[サンプルコード]
public class Sample {
    
    public static void main(final String[] args) {

        outputMap("Match String", Optional.of("one"));
        outputMap("Not Match String", Optional.of("two"));
        outputMap("Empty String", Optional.of(""));
        outputMap("Null", Optional.empty()); 
    }

   private static void outputMap(final String label, final Optional<String> value) {

        System.out.println("===================== " + label + "  ====================="); 

        final Optional<Integer> chengedOptional = value.map(v -> {
            if ("one".equals(v)) {

                return 1;
            }

            return 0;
        });

        System.out.println("Changed to number isPresent? " + chengedOptional.isPresent());
        chengedOptional.ifPresent(v -> System.out.println("Changed to number :" + v));

        System.out.println("===================== " + label + "  ====================="); 
    }
}

Optional#mapメソッドのパラメータは
Optionalオブジェクトの値の型をもらい、任意のオブジェクトを返す
関数オブジェクトです。

サンプルでは"one"と一致した場合は1に変換し、
それ以外は0に変換しています。
Optionalの値をisPresent/ifPresentメソッドで出力しています。

[出力結果]

結果は少し見やすくするために実際の結果から
余分な改行を入れています。

===================== Match String  =====================
Changed to number isPresent? true
Changed to number :1
===================== Match String  =====================

===================== Not Match String  =====================
Changed to number isPresent? true
Changed to number :0
===================== Not Match String  =====================

===================== Empty String  =====================
Changed to number isPresent? true
Changed to number :0
===================== Empty String  =====================

===================== Null  =====================
Changed to number isPresent? false
===================== Null  =====================

値が"one"の場合に1に変換されて、
それ以外は0に変換されているのがわかります。

Nullの場合、Optionalオブジェクトの値は設定されませんが
Optionalオブジェクト自体が返却されています。

【filterメソッド】

つづいてfilterメソッドから見ていきます。

[サンプルコード]
public class Sample {
    
    public static void main(final String[] args) {

        outputFilter("Match String", Optional.of("one"));
        outputFilter("Not Match String", Optional.of("two"));
        outputFilter("Empty String", Optional.of(""));
        outputFilter("Null", Optional.empty());     }

    private static void outputFilter(final String label, final Optional<String> value) {

        System.out.println("===================== " + label + "  ====================="); 

        final Optional<String> filtedValue = value
                .filter(v -> {
                        System.out.println("Filter execute!");
                        return "one".equals(v);
                    });

        System.out.println("Filtered value isPresent? " + filtedValue.isPresent());
        filtedValue.ifPresent(v -> System.out.println("Filtered value :" + v));

        System.out.println("===================== " + label + "  ====================="); 
    }
}

Optional#filterメソッドのパラメータは
Optionalオブジェクトの値の型をもらい、booleanを返す
関数オブジェクトです。

サンプルではコンソールに文字を出力し、
値が"one"かどうかをフィルタしています。
Optionalの値をisPresent/ifPresentメソッドで出力しています。

[実行結果]

結果はmapの時と同じく整形しています。

===================== Match String  =====================
Filter execute!
Filtered value isPresent? true
Filtered value :one
===================== Match String  =====================

===================== Not Match String  =====================
Filter execute!
Filtered value isPresent? false
===================== Not Match String  =====================

===================== Empty String  =====================
Filter execute!
Filtered value isPresent? false
===================== Empty String  =====================

===================== Null  =====================
Filtered value isPresent? false
===================== Null  =====================

"one"に一致する値の場合にのみ
Optionalオブジェクトの値が設定されていることがわかります。

それ以外の値に関しては
Optionalオブジェクトは返ってきていますが、
値は設定されていません。

また、filterメソッド内でコンソール出力していますが、
Null以外の場合は出力されていますが、
Nullの場合は出力されていません。

つまり、Nullの場合はfilterメソッドが実行されない
と言うことがわかります。

【まとめ】

map/filterメソッドの動きを見てみましたが、
どちらもOptionalオブジェクト自体が返却されています。

map/filterメソッドとisPresent/ifPresentメソッドを
組み合わせて使うとNullPointerException
心配をする必要なく処理を書くことができます。

あくまでOptionalの中に値に対してなので、
Optional自体がNullの場合は発生してしまいますが・・・