假设我有这个方法
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
我的问题是,由于OrElse and OrElseGet
返回<T>
而不是Optional<T>
,是否有一种本机方法可以将其重写为更具功能性的方式,而不需要几个松散耦合的返回语句?
编辑
我想逐一检查验证,因为它们是外部的并且很重。这样,我只会把必要的称为
添加Optional.or
就是为了解决这种情况。它是在Java 9中添加的,所以如果你还在使用Java 8,那么你就不能使用它
return validateItem(s.getItem())
.or(() -> validatePayment(req.getPayment()))
.or(() -> /*another one*/);
如果你被困在Java8上,你可以写一个辅助方法
public static <T> Optional<T> firstNonEmpty(List<Supplier<Optional<T>>> supplierList) {
for (Supplier<Optional<T>> supplier : supplierList) {
Optional<T> value = supplier.get();
if (value.isPresent()) return value;
}
return Optional.empty();
}
它是这样使用的:
return firstNonEmpty(
Arrays.asList(
() -> validateItem(s.getItem()),
() -> validatePayment(req.getPayment()),
() -> /*another one*/
)
);
只需使用or
:
如果存在值,则返回描述该值的
Optional
,否则返回由提供函数生成的Optional
。
return validatePayment(s.getItem()).or(() -> validatePayment(s.getPayment()));
如果您有一个长的/动态的项目列表要验证,您可能需要使用一个流:
return Stream.<Supplier<String>>of(s::getItem, req::getPayment, ...)
.map(s -> this.validateItem(s.get()))
.filter(Predicate.not(Optional::isEmpty)) //or filter(o -> !o.isEmpty())
.findFirst();