Java 从一个或另一个选项中获取值
我有两个Java 从一个或另一个选项中获取值,java,java-8,optional,Java,Java 8,Optional,我有两个java.util.Optional实例,我想得到一个Optional,它可以是: 具有第一个可选项的值(如果具有值) 具有第二个可选值(如果有值) 为空,则两个选项都没有值 是否有一种直接的方法可以做到这一点,即是否已经有一些API可以做到这一点 下面的表达式可以做到这一点,但我必须两次提到第一个可选选项: firstOptional.isPresent() ? firstOptional : secondOptional 这正是com.google.common.base.Op
java.util.Optional
实例,我想得到一个Optional
,它可以是:
- 具有第一个可选项的值(如果具有值)
- 具有第二个可选值(如果有值)
- 为空,则两个选项都没有值
firstOptional.isPresent() ? firstOptional : secondOptional
这正是com.google.common.base.Optional.or()所做的,但是Java8的API中没有该方法
aioobe所接受的答案列出了一些替代方法,以克服可选API的遗漏,其中必须计算此类值(这回答了我的问题)。我现在选择在代码库中添加一个实用函数:
public static <T> Optional<T> or(Optional<T> a, Optional<T> b) {
if (a.isPresent())
return a;
else
return b;
}
公共静态可选或(可选a、可选b){
如果(a.isPresent())
返回a;
其他的
返回b;
}
Java 9及以上版本:
Java 8及以下版本
如果您想避免两次提到firstOptional
,那么您可能需要使用类似
firstOptional.map(Optional::of).orElse(secondOptional);
Optional<...> opt = optionals.stream()
.filter(Optional::isPresent)
.findFirst()
.orElse(Optional.empty());
或
但最具可读性的变体可能是简单地执行
Optional<...> opt = firstOptional.isPresent() ? firstOptional
: secondOptional.isPresent() ? secondOptional
: Optional.empty();
Optional opt=firstOptional.isPresent()?第一可选
:second可选。isPresent()?第二可选
:可选。空();
如果有人偶然发现了这个问题,但有一个选项列表,我建议如下
firstOptional.map(Optional::of).orElse(secondOptional);
Optional<...> opt = optionals.stream()
.filter(Optional::isPresent)
.findFirst()
.orElse(Optional.empty());
Optional opt=optionals.stream()
.filter(可选::isPresent)
.findFirst()
.orElse(可选.empty());
编辑:我完全以为你最初使用的是番石榴的可选
。我已经更新了我的答案,为各自的可选类提供了Guava和Java8语法
Java 8可选
您可以将其缩短为:
firstOptional.orElse(secondOptional.orElse(EMPTY_VALUE))
firstOptional.or(secondOptional.or(EMPTY_VALUE))
我不知道你在第三颗子弹里说的“空”是什么意思。如果您的意思是null,那么这就可以了:
firstOptional.orElse(secondOptional.orElse(null))
firstOptional.or(secondOptional.orNull())
orElse()
是Optional
上的一个方法,它将返回值(如果存在),否则它将返回您作为参数提供给orElse()
的值
番石榴可选
您可以将其缩短为:
firstOptional.orElse(secondOptional.orElse(EMPTY_VALUE))
firstOptional.or(secondOptional.or(EMPTY_VALUE))
我不知道你在第三颗子弹里说的“空”是什么意思。如果您的意思是null,那么这就可以了:
firstOptional.orElse(secondOptional.orElse(null))
firstOptional.or(secondOptional.orNull())
或()?它是为像你这样的箱子而设计的。另外一个好处是,在列表中添加额外的服务非常容易
下面是一个描述该模式的链接:我遇到了一个问题,这个问题可能已经用JDK 9Optional::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());
}
@SafeVarargs
公共静态可选首件(最终供应商…可选){
返回流(可选)
.map(供应商::获取)
.filter(可选::isPresent)
.findFirst()
.orElse(可选.empty());
}
现在,您可以为该方法提供任意数量的选项,它们将按照如下方式进行惰性评估:
final Optional<String> username = OptionalUtil.firstPresent(
() -> findNameInUserData(user.getBasicData()),
() -> findNameInUserAddress(user.getAddress()),
() -> findDefaultUsername());
final Optional username=OptionalUtil.firstPresent(
()->findNameInUserData(user.getBasicData()),
()->findNameInUserAddress(user.getAddress()),
()->findDefaultUsername());
现在,只有当findNameInUserData
返回空时,才会调用findNameInUserAddress
findDefaultUsername
仅在findNameUserData
和findNameUserAddress
返回空等情况下才会被调用。您使用的选项类型是什么?没有这个方法*facepalm*我误以为OP使用的是Guava的可选而不是Java8。我更新了我的答案以显示两者的语法。我所说的“空”是指Optional.empty()
。我希望能够在生成的可选项上使用ifPresent()
。对于Java 8示例,这将打开可选项,这样您就只剩下一个T。您的第三个示例不会返回可选项吗,因为findFirst正在流上操作?您需要stream().filter(可选::isPresent).map(o->o.get()).findFirst()我认为值得一提的是,Java 8与Java 9的等价物可选。或者是firstOptional.map(可选::of).orElseGet(()->secondOptional)
。只有当firstOptional
为空时,它才会计算secondOptional
。行为类似于逻辑的|
。如果您选择使用实用功能,我建议使用供应商
作为第二个参数,以便在第一个参数存在时支持短路。@r0estir0bbe这肯定是一个选项。我认为这两个参数在我最初需要的实例中计算起来非常便宜。如果是在我之后,我会给哈斯克尔写信,这样我就不用去想它了这如何适用于我的问题,这是关于组合两个可选的
实例的问题?您能否举例说明使用此模式实现的外观?