Yon*_*ree 128 java lambda optional java-8 java-9
我一直在使用Java 8中的新Optional类型,我遇到了似乎是功能上不支持的常见操作:"orElseOptional"
考虑以下模式:
Optional<Result> resultFromServiceA = serviceA(args);
if (resultFromServiceA.isPresent) return result;
else {
Optional<Result> resultFromServiceB = serviceB(args);
if (resultFromServiceB.isPresent) return resultFromServiceB;
else return serviceC(args);
}
Run Code Online (Sandbox Code Playgroud)
这种模式有很多种形式,但归结为在一个可选项上需要一个"orElse",它接受一个生成一个新的可选项的函数,只有当前的一个不存在时才被调用.
它的实现看起来像这样:
public Optional<T> orElse(Supplier<Optional<? extends T>> otherSupplier) {
return value != null ? this : other.get();
}
Run Code Online (Sandbox Code Playgroud)
我很好奇是否有这样的方法不存在的原因,如果我只是以一种无意的方式使用Optional,以及人们提出了处理这种情况的其他方式.
我应该说,我认为涉及自定义实用程序类/方法的解决方案并不优雅,因为使用我的代码的人不一定知道它们存在.
另外,如果有人知道,这样的方法是否会包含在JDK 9中,我可以在哪里提出这样的方法?对我来说,这似乎是对API的一个相当明显的遗漏.
Nic*_*lai 79
这是的形式JDK 9的一部分or,这需要一个Supplier<Optional<T>>.那么你的例子就是:
return serviceA(args)
.or(() -> serviceB(args))
.or(() -> serviceC(args));
Run Code Online (Sandbox Code Playgroud)
Hol*_*ger 60
鉴于当前的API,最干净的"尝试服务"方法将是:
Optional<Result> o = Stream.<Supplier<Optional<Result>>>of(
()->serviceA(args),
()->serviceB(args),
()->serviceC(args),
()->serviceD(args))
.map(Supplier::get)
.filter(Optional::isPresent)
.map(Optional::get)
.findFirst();
Run Code Online (Sandbox Code Playgroud)
重要的方面不是您必须编写一次的(常量)操作链,而是添加其他服务(或修改服务列表是一般的)是多么容易.在这里,添加或删除单个()->serviceX(args)就足够了.
由于对流的延迟评估,如果前面的服务返回非空,则不会调用任何服务Optional.
Mis*_*sha 32
它不漂亮,但这将工作:
return serviceA(args)
.map(Optional::of).orElseGet(() -> serviceB(args))
.map(Optional::of).orElseGet(() -> serviceC(args))
.map(Optional::of).orElseGet(() -> serviceD(args));
Run Code Online (Sandbox Code Playgroud)
.map(func).orElseGet(sup)是一个相当方便的模式使用Optional.这意味着"如果这Optional包含价值v,请给我func(v),否则给我sup.get()".
在这种情况下,我们打电话serviceA(args)给一个Optional<Result>.如果它Optional包含值v,我们想得到Optional.of(v),但如果它是空的,我们想得到serviceB(args).用更多替代品冲洗重复.
这种模式的其他用途是
.map(Stream::of).orElseGet(Stream::empty).map(Collections::singleton).orElseGet(Collections::emptySet)aio*_*obe 26
也许这就是你所追求的:从一个或另一个获得价值
否则,你可能想看看Optional.orElseGet.这是我认为你所追求的一个例子:
result = Optional.ofNullable(serviceA().orElseGet(
() -> serviceB().orElseGet(
() -> serviceC().orElse(null))));
Run Code Online (Sandbox Code Playgroud)
假设您仍在使用 JDK8,则有多种选择。
例如:
public class Optionals {
static <T> Optional<T> or(Supplier<Optional<T>>... optionals) {
return Arrays.stream(optionals)
.map(Supplier::get)
.filter(Optional::isPresent)
.findFirst()
.orElseGet(Optional::empty);
}
}
Run Code Online (Sandbox Code Playgroud)
这样你就可以:
return Optionals.or(
()-> serviceA(args),
()-> serviceB(args),
()-> serviceC(args),
()-> serviceD(args)
);
Run Code Online (Sandbox Code Playgroud)
例如 google guava 的 Optional 支持正确的or()操作(就像 JDK9),例如:
return serviceA(args)
.or(() -> serviceB(args))
.or(() -> serviceC(args))
.or(() -> serviceD(args));
Run Code Online (Sandbox Code Playgroud)
(其中每个服务返回com.google.common.base.Optional,而不是java.util.Optional)。
| 归档时间: |
|
| 查看次数: |
65720 次 |
| 最近记录: |