Optionalについて調べてみた その4
【概要】
今回は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の場合は発生してしまいますが・・・