Feu*_*mel 48 java optional java-8
我有两个java.util.Optional实例,我想得到一个Optional:
是否有直接的方法来做到这一点,即是否已经有一些API来做到这一点?
以下表达式会这样做,但我必须提到第一个可选的两次:
firstOptional.isPresent() ? firstOptional : secondOptional
Run Code Online (Sandbox Code Playgroud)
这正是com.google.common.base.Optional.or()如此,但Java 8的API中不存在该方法.
aioobe接受的答案列出了一些替代方法来克服这种遗漏OptionalAPI的权利,在这种情况下必须计算这样的值(这回答了我的问题).我现在选择在我的代码库中添加一个实用程序函数:
public static <T> Optional<T> or(Optional<T> a, Optional<T> b) {
if (a.isPresent())
return a;
else
return b;
}
Run Code Online (Sandbox Code Playgroud)
aio*_*obe 65
更新:从Java 9(变更集12885)开始,您可以这样做
firstOptional.or(() -> secondOptional);
Run Code Online (Sandbox Code Playgroud)
对于Java 8,请继续阅读......
如果你想避免提firstOptional两次,你可能不得不采取类似的方式
firstOptional.map(Optional::of).orElse(secondOptional);
Run Code Online (Sandbox Code Playgroud)
要么
Optional.ofNullable(firstOptional.orElse(secondOptional.orElse(null)));
Run Code Online (Sandbox Code Playgroud)
但最可读的变体可能就是这样做
Optional<...> opt = firstOptional.isPresent() ? firstOptional
: secondOptional.isPresent() ? secondOptional
: Optional.empty();
Run Code Online (Sandbox Code Playgroud)
如果有人偶然发现了这个问题,但有一个可选项列表,我会建议像
Optional<...> opt = optionals.stream()
.filter(Optional::isPresent)
.findFirst()
.orElse(Optional.empty());
Run Code Online (Sandbox Code Playgroud)
编辑:我完全以为你最初使用的是番石榴Optional.我已经更新了我的答案,为他们各自的Optional类提供了Guava和Java 8语法.
Java 8可选
你可以缩短它:
firstOptional.orElse(secondOptional.orElse(EMPTY_VALUE))
Run Code Online (Sandbox Code Playgroud)
我不确定你的第三个子弹是什么意思"空".如果你的意思是null那么这就行了:
firstOptional.orElse(secondOptional.orElse(null))
Run Code Online (Sandbox Code Playgroud)
orElse()是一个方法Optional,如果存在,将返回值,否则它将返回您作为参数提供的值orElse().
番石榴可选
你可以缩短它:
firstOptional.or(secondOptional.or(EMPTY_VALUE))
Run Code Online (Sandbox Code Playgroud)
我不确定你的第三个子弹是什么意思"空".如果你的意思是null那么这就行了:
firstOptional.or(secondOptional.orNull())
Run Code Online (Sandbox Code Playgroud)
or()是一个方法Optional,如果存在,将返回值,否则它将返回您作为参数提供的值or().
小智 7
我遇到了一些可能已经用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());
}
Run Code Online (Sandbox Code Playgroud)
现在你可以为这个方法提供任意数量的选项,它们将被懒惰地评估,如下所示:
final Optional<String> username = OptionalUtil.firstPresent(
() -> findNameInUserData(user.getBasicData()),
() -> findNameInUserAddress(user.getAddress()),
() -> findDefaultUsername());
Run Code Online (Sandbox Code Playgroud)
现在,findNameInUserAddress只有在findNameInUserData返回为空时才会被调用.findDefaultUsername将仅都叫findNameInUserData并findNameInUserAddress返回空等.