在Java 8中,我想对一个Optional对象做一些事情,如果它存在,并做另一件事,如果它不存在.
if (opt.isPresent()) {
System.out.println("found");
} else {
System.out.println("Not found");
}
Run Code Online (Sandbox Code Playgroud)
但这不是一种"功能风格".
Optional有一个ifPresent()方法,但我无法链接一个orElse()方法.
因此,我不能写:
opt.ifPresent( x -> System.out.println("found " + x))
.orElse( System.out.println("NOT FOUND"));
Run Code Online (Sandbox Code Playgroud)
在回复@assylias时,我认为不适Optional.map()用于以下情况:
opt.map( o -> {
System.out.println("while opt is present...");
o.setProperty(xxx);
dao.update(o);
return null;
}).orElseGet( () -> {
System.out.println("create new obj");
dao.save(new obj);
return null;
});
Run Code Online (Sandbox Code Playgroud)
在这种情况下,当opt存在时,我更新其属性并保存到数据库.当它不可用时,我创建一个新的obj并保存到数据库.
请注意我必须返回的两个lambda null.
但是当opt存在时,两个lambdas都将被执行.obj将更新,并将新对象保存到数据库.这是因为return null在第一个lambda中.并且orElseGet()将继续执行.
我一直在使用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的一个相当明显的遗漏.
这是我到目前为止所得到的:
Optional<Foo> firstChoice = firstChoice();
Optional<Foo> secondChoice = secondChoice();
return Optional.ofNullable(firstChoice.orElse(secondChoice.orElse(null)));
Run Code Online (Sandbox Code Playgroud)
这让我觉得既丑陋又浪费.如果firstChoice存在,我不必要地计算secondChoice.
还有一个更高效的版本:
Optional<Foo> firstChoice = firstChoice();
if(firstChoice.isPresent()) {
return firstChoice;
} else {
return secondChoice();
}
Run Code Online (Sandbox Code Playgroud)
在这里,我无法将一些映射函数链接到最终,而无需复制映射器或声明另一个局部变量.所有这些使得代码比实际解决的问题更复杂.
我宁愿写这个:
return firstChoice().alternatively(secondChoice());
Run Code Online (Sandbox Code Playgroud)
但是Optional ::或者显然不存在.怎么办?
假设我有这个方法
public Optional<String> validateAndReturnErrorMessage(SomeEcommerceSale s) {
Optional<String> errorWithItem = validateItem(s.getItem());
if (errorWithItem.isPresent()) return errorWithItem;
Optional<String> errorWithPayment = validatePayment(s.getPayment());
if (errorWithPayment.isPresent()) return errorWithPayment;
// assume I have several other cases like the 2 above
return Optional.empty(); // meaning there were no errors
Run Code Online (Sandbox Code Playgroud)
我的问题是,由于OrElse and OrElseGetreturn<T>而不是Optional<T>,是否有一种本地方法可以将其重写为更实用的方式,而无需几个松散耦合的 return 语句?
编辑
我想一一检查验证,因为它们是外部且沉重的。这样,我只会调用必要的
我有三个java8 Optionals,并希望返回以首选顺序实际存在的任何一个.似乎应该有一种简单的方法来链接它们:
return optionalA.orElseIfPresent(optionalB).orElseIfPresent(optionalC);
Run Code Online (Sandbox Code Playgroud)
如果这三个都是空的,则Optional.empty()应该返回.
现有的orElse和orElseGet并没有真正完成任务 - 它们必须返回一个实际值,因此剩下的后备不可能是Optionals本身.
在最糟糕的情况下,我可以有一长串ifPresent()检查,但似乎有一个更好的方法去实现它?