【发布时间】:2019-11-15 20:12:37
【问题描述】:
我有一个 java 8 功能接口,它接受应用于对象的验证器列表并返回验证结果。验证结果在reduce阶段累积。代码如下:
public interface LogicalTableValidator extends Function<LogicalTable, ValidationResult> {
static LogicalTableValidator addAll(LogicalTableValidator... validators) {
// Need to break out of this validator stream, based on the criticality of a particular validation error
return logicalTable -> Arrays.stream(validators).map(v -> v.apply(logicalTable))
.reduce(new ValidationResult(logicalTable.getUid()), (validationResult, currentResult) -> {
validationResult.addValidationMessages(currentResult.getValidationMessages());
return validationResult;
});
}
}
从这里调用此验证逻辑
LogicalTableValidator logicalTableValidators = LogicalTableValidator.addAll(getValidators());
List<ValidationResult> ltValidationResults = logicalTables.stream()
.parallel()
.map(logicalTableValidators)
.collect(Collectors.toList());
我面临的问题是,我无法有条件地脱离验证逻辑。当我在逻辑对象上应用验证器时就是这种情况,如果验证失败并出现严重错误,我不需要运行其余的验证器。相反,我需要在此处停止验证过程。
解决方法是不使用 lambda 表达式进行验证,而是使用以下代码。
return new LogicalTableValidator() {
@Override
public ValidationResult apply(LogicalTable t) {
ValidationResult result = new ValidationResult(t.getUid());
for (LogicalTableValidator validator : validators) {
ValidationResult currentResult = validator.apply(t);
List<ValidationMessage> messages = currentResult.getValidationMessages();
Boolean exit = false;
for (ValidationMessage message : messages) {
if(StringUtils.equalsIgnoreCase(message.getSeverity(), "1")) {
exit = true;
break;
}
}
result.addValidationMessages(currentResult.getValidationMessages());
if (exit) break;
}
return result;
}
};
看来,不在函数式接口中使用 lambda 表达式,违背了使用函数式接口的目的,但我想不出有条件地跳出验证循环的方法。我可以使用任何替代方法吗?这段代码应该以不同的方式构造吗?
【问题讨论】:
-
为什么不使用 filter()?
-
filter() 仍将遍历所有对象以检查过滤条件。如果遇到严重错误,我想跳出循环。
标签: java lambda mapreduce java-stream functional-interface