動機
Optionalについて、うまく使えていない気がするため、改めて整理してみる。
実装例
Nullチェック
nullの一番の問題点は、nullチェックを行わなくともコンパイルエラーにならないこと。そして実行時にNullPointerExceptionが発生する可能性があること。
例として、nullチェックを行う場合について考えてみる。
public String getFruit() {
return 果物の名前または、nullを返却する処理とする;
}
public void fruitCheck() {
var fruit = getFruit();
if (fruit != null) {
System.out.println(fruit + " are delicious.");
}
}
これを単純にOptionalに置き換えると下記のようになる。
public Optional<String> getFruit() {
String name = 果物の名前または、nullを返却する処理とする;
return Optional.ofNullable(name);
}
public void fruitCheck() {
var fruit = getFruit();
if (fruit.isPresent()) {
System.out.println(fruit.get() + " are delicious.");
}
}
これだと、nullチェックを行っているときと変わらない。この処理を典型的な関数型プログラミングのスタイルに書き換えてみる。
public void fruitCheck() {
var fruit = getFruit();
fruit.ifPresent(name -> System.out.println(name + " are delicious."));
}
elseの処理が必要な場合は、下記のように書ける。
fruit.ifPresentOrElse(name -> System.out.println(name + " are delicious."),
() -> System.out.println("I'm hungry."));
Nullの場合にデフォルト値を設定する処理
getFruit()のメソッドでnullを返すのではなく、nullの場合デフォルトの値を返す場合を考えてみる。
public String getFruit() {
String name = 果物の名前または、nullを返却する処理とする;
if (name != null) {
return name;
} else {
return "Apple";
}
}
public void fruitCheck() {
var fruit = getFruit();
System.out.println(fruit + " are delicious.");
}
Optionalに置き換えると下記のようになる。
public String getFruit() {
String name = 果物の名前または、nullを返却する処理とする;
return Optional.ofNullable(name).orElse("Apple");
}
関数型プログラミングのスタイルになって、Nullチェックのミスも減るだろうか。
Nullチェックするとともに値のチェックも行う場合
public void fruitCheck() {
var fruit = getFruit();
if (fruit != null && fruit.equals("Banana")) {
System.out.println(fruit + " are very delicious.");
}
}
public void fruitCheck() {
var fruit = getFruit();
fruit.filter(name -> name.equals("Banana"))
.ifPresent(name -> System.out.println(name + " are delicious."));
}