2つの_Java.util.Optional
_インスタンスがあり、次のいずれかのOptional
を取得したい:
それを行う簡単な方法はありますか?つまり、それを行うためのAPIがすでにありますか?
次の式でそれを行いますが、最初のオプションは2回言及する必要があります。
_firstOptional.isPresent() ? firstOptional : secondOptional
_
これはcom.google.common.base.Optional.or()
が行うこととまったく同じですが、そのメソッドはJava 8のAPIには存在しません。
aioobeによって受け入れられた回答には、このようなOptional
APIの省略を克服するためのいくつかの代替アプローチがリストされています。コードベースにユーティリティ関数を追加することにしました:
_public static <T> Optional<T> or(Optional<T> a, Optional<T> b) {
if (a.isPresent())
return a;
else
return b;
}
_
更新:Java 9( changeset 12885 )の時点でできること
firstOptional.or(() -> secondOptional);
Java 8、続きを読む...
firstOptional
に2回言及することを避けたい場合は、おそらく次のようなものを使用する必要があります。
firstOptional.map(Optional::of).orElse(secondOptional);
または
Optional.ofNullable(firstOptional.orElse(secondOptional.orElse(null)));
しかし、最も読みやすいバリアントは、おそらく単純に
Optional<...> opt = firstOptional.isPresent() ? firstOptional
: secondOptional.isPresent() ? secondOptional
: Optional.empty();
誰かがこの質問に出くわしたが、オプションのlistがある場合は、次のようなものをお勧めします
Optional<...> opt = optionals.stream()
.filter(Optional::isPresent)
.findFirst()
.orElse(Optional.empty());
EDIT:もともとGuavaのOptional
を使用していると思いました。回答を更新して、それぞれのOptional
クラスにGuavaとJava 8構文の両方を提供します。
Java 8オプション
これまで短縮できます:
_firstOptional.orElse(secondOptional.orElse(EMPTY_VALUE))
_
「空」という3番目の箇条書きの意味はわかりません。 nullを意味する場合、これはトリックを行います:
_firstOptional.orElse(secondOptional.orElse(null))
_
orElse()
はOptional
のメソッドであり、存在する場合は値を返します。それ以外の場合は、orElse()
の引数として指定した値を返します。
グアバオプション
これまで短縮できます:
_firstOptional.or(secondOptional.or(EMPTY_VALUE))
_
「空」という3番目の箇条書きの意味はわかりません。 nullを意味する場合、これはトリックを行います:
_firstOptional.or(secondOptional.orNull())
_
or()
はOptional
のメソッドであり、存在する場合は値を返します。それ以外の場合は、or()
の引数として指定した値を返します。
JDK 9で解決された可能性のある問題に何度か遭遇しましたOptional::or
そして、JDK 8を使用しているためできませんでした。最後に、このメソッドでutilクラスを追加しました。
@SafeVarargs
public static <T> Optional<T> firstPresent(final Supplier<Optional<T>>... optionals) {
return Stream.of(optionals)
.map(Supplier::get)
.filter(Optional::isPresent)
.findFirst()
.orElse(Optional.empty());
}
これで、このメソッドに任意の数のオプションを提供でき、次のように遅延評価されます。
final Optional<String> username = OptionalUtil.firstPresent(
() -> findNameInUserData(user.getBasicData()),
() -> findNameInUserAddress(user.getAddress()),
() -> findDefaultUsername());
現在、findNameInUserAddress
は、findNameInUserData
が空を返す場合にのみ呼び出されます。 findDefaultUsername
とfindNameInUserData
の両方が空などを返す場合にのみ、findNameInUserAddress
が呼び出されます。