Java 从一个 Optional 或另一个获取价值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24599996/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Get value from one Optional or another
提问by Feuermurmel
I have two java.util.Optional
instances and I want to get an Optional
that either:
我有两个java.util.Optional
实例,我想得到一个Optional
:
- Has the value of the first Optional, if it has a value.
- Has the value of the second Optional, if it has a value.
- Is empty of neither Optional has a value.
- 具有第一个 Optional 的值,如果它有值的话。
- 具有第二个 Optional 的值,如果它有值的话。
- 空的 Optional 都没有值。
Is there a straight-forward way to do that, i.e. is there already some API to do that?
有没有一种直接的方法可以做到这一点,即是否已经有一些 API 可以做到这一点?
The following expressions will do that, but I have to mention the first optional twice:
下面的表达式可以做到这一点,但我必须两次提到第一个可选:
firstOptional.isPresent() ? firstOptional : secondOptional
This is exactly what com.google.common.base.Optional.or()
does, but that method is not present in Java 8's API.
这正是这样com.google.common.base.Optional.or()
做的,但该方法在 Java 8 的 API 中不存在。
The accepted answer by aioobelists a few alternative approaches to overcome this omission of the Optional
API right where such a value has to be computed (which answers my question). I've now opted to add a utility function to my codebase:
aioobe接受的答案列出了一些替代方法来克服Optional
API 的这种遗漏,其中必须计算这样的值(这回答了我的问题)。我现在选择向我的代码库添加一个实用程序函数:
public static <T> Optional<T> or(Optional<T> a, Optional<T> b) {
if (a.isPresent())
return a;
else
return b;
}
采纳答案by aioobe
Java 9 and above:
Java 9 及更高版本:
firstOptional.or(() -> secondOptional);
Java 8 and below
Java 8 及以下
If you want to avoid mentioning firstOptional
twice, you'd probably have to go with something like
如果你想避免提及firstOptional
两次,你可能不得不使用类似的东西
firstOptional.map(Optional::of).orElse(secondOptional);
or
或者
Optional.ofNullable(firstOptional.orElse(secondOptional.orElse(null)));
But the most readable variant is probably to simply do
但最易读的变体可能就是简单地做
Optional<...> opt = firstOptional.isPresent() ? firstOptional
: secondOptional.isPresent() ? secondOptional
: Optional.empty();
If someone stumbles across this question but has a listof optionals, I'd suggest something like
如果有人偶然发现这个问题但有一个可选列表,我会建议像
Optional<...> opt = optionals.stream()
.filter(Optional::isPresent)
.findFirst()
.orElse(Optional.empty());
回答by Erik Gillespie
EDIT:I totally thought you were using Guava's Optional
originally. I've updated my answer to supply both Guava and Java 8 syntax for their respective Optional
classes.
编辑:我完全认为您最初使用的是番石榴Optional
。我已经更新了我的答案,为它们各自的Optional
类提供 Guava 和 Java 8 语法。
Java 8 Optional
Java 8 可选
You can shorten it up to this:
您可以将其缩短为:
firstOptional.orElse(secondOptional.orElse(EMPTY_VALUE))
I'm not sure what you meant in your third bullet by "empty". If you meant null then this'll do the trick:
我不确定你在第三个项目中的“空”是什么意思。如果您的意思是 null 那么这将起作用:
firstOptional.orElse(secondOptional.orElse(null))
orElse()
is a method on Optional
that will return the value if present, otherwise it will return the value you supplied as the argument to orElse()
.
orElse()
是一个方法Optional
,如果存在,它将返回值,否则它将返回您作为参数提供给 的值orElse()
。
Guava Optional
番石榴 可选
You can shorten it up to this:
您可以将其缩短为:
firstOptional.or(secondOptional.or(EMPTY_VALUE))
I'm not sure what you meant in your third bullet by "empty". If you meant null then this'll do the trick:
我不确定你在第三个项目中的“空”是什么意思。如果您的意思是 null 那么这将起作用:
firstOptional.or(secondOptional.orNull())
or()
is a method on Optional
that will return the value if present, otherwise it will return the value you supplied as the argument to or()
.
or()
是一个方法Optional
,如果存在,它将返回值,否则它将返回您作为参数提供给 的值or()
。
回答by kaba713
I know this question is old, but why don't just use in this kind of cases something proven like Chain-of-responsibility pattern? It is made/designed for cases like yours. And as an additional benefit it's quite easy to add additional services to the list.
我知道这个问题很老,但为什么不在这种情况下使用已经证明的责任链模式之类的东西?它是为像您这样的情况而制造/设计的。作为额外的好处,可以很容易地向列表中添加额外的服务。
Here is a link that describes the Pattern: https://sourcemaking.com/design_patterns/chain_of_responsibility
这是描述模式的链接:https: //sourcemaking.com/design_patterns/chain_of_responsibility
回答by jahmaican
I had a few encounters with a problem that might've been solved with JDK 9 Optional::or
and couldn't because we use JDK 8. Finally I added a util class with this method:
我遇到了一些问题,这个问题可能已经用 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());
}
Now you can supply any number of optionals to this method and they'll be lazily evaluated like so:
现在你可以为这个方法提供任意数量的选项,它们会像这样被懒惰地评估:
final Optional<String> username = OptionalUtil.firstPresent(
() -> findNameInUserData(user.getBasicData()),
() -> findNameInUserAddress(user.getAddress()),
() -> findDefaultUsername());
Now, findNameInUserAddress
will only be called if findNameInUserData
returns empty. findDefaultUsername
will only be called if both findNameInUserData
and findNameInUserAddress
return empty etc.
现在,findNameInUserAddress
只有在findNameInUserData
返回空时才会被调用。findDefaultUsername
将仅都叫findNameInUserData
和findNameInUserAddress
空车返回等。