JavaのOptional型について


Java SE 8から新たに追加されたOptionalを使うとnullになりうる型として明示できます。これによりNullPointerExceptionを防ぎ、安全にnullを扱うことができます。

🚜 Optionalの基礎

Optionalを使わない場合はif文でnullチェックを行っていました。

Article article = getArticle();
if (article != null) {
article.getTitle();
}

Optionalを利用することで、値が存在する場合だけ処理を行うことを明示的に記述できます。

Optional
optionalArticle = Optional.ofNullable(getArticle());

optionalArticle.ifPresent(article -> article.getTitle());

😎 Optionalの生成

Optionalコンストラクタの生成メソッドofofNullableの紹介です。

StringBuilder sb = null;
Optional osb = Optional.of(sb); // NullPointerException(例外)が発生

Optional osb2 = Optional.ofNullable(sb); // nullを受け入れる

これ以外に基本変数型のためにOptionalIntOptionalLongOptionalDoubleがあります。

OptionalInt optionalInt = OptionalInt.of(1);
OptionalLong optionalLong = OptionalLong.of(10L);
OptionalDouble optionalLong = OptionalDouble.of(10.0);

🐡 Optionalから

Optionalインスタンスを使うと、nullチェックを含めた値の取得を行うことができます。

StringBuilder sb = null; // or sb = new StringBuilder(hoge)
Optional osb = Optional.ofNullable(sb);

// opt == null なら NoSuchElementException
// opt != null なら StringBuilderのインスタンスを返す
StringBuilder sb1 = osb.get(new StringBuilder(none))

// osb == null なら new StringBuilder(none) を返す
// osb != null なら 単純な取り出し
StringBuilder sb2 = osb.orElse(new StringBuilder(none));

// osb == null なら何もしない
// osb != ならラムダ式を実行
osb.ifPresent(sb -> {
sb.insert(0, []);
sb.append(]);
});

🚌 Optionalを処理してOptionalを返すメソッド

### 条件に一致する場合のみ値をセット:filter

Optional optArticle = Optional.ofNullable(getArticle());
Optional filteredArticle = optArticle.filter(article -> article.getTitle().length() >= 2);

特定の処理をして結果をセット:map

Optional str = Optional.of("article").map(String::toUpperCase);
System.out.println(str); //=> Article

🐠 Optionalによるnullチェックや置換え

多段でnullチェックをして値を取り出すのではなく、Optionalを使ってnullチェックを行うことでコードの可読性を向上できます。

// コンストラクタなどは省略しています
class Name {
private final Optional first;
Optional getFirst() {
return this.first;
}
}

class Person {
private final Optional name;
Optional getName() {
return this.name;
}
}

void showPersonFirstName(Optional person) {
person.flatMap(Person:getName) // getNameの結果をOptionalで返す
.flatMap(Name::getFirst) // getFirstの結果をOptionalで返す
.ifPresent(System.out::Println); // nullでなければprintln
}

😀 参照リンク

🖥 VULTRおすすめ

VULTR」はVPSサーバのサービスです。日本にリージョンがあり、最安は512MBで2.5ドル/月($0.004/時間)で借りることができます。4GBメモリでも月20ドルです。 最近はVULTRのヘビーユーザーになので、「ここ」から会員登録してもらえるとサービス開発が捗ります!

📚 おすすめの書籍