返回第一个结果匹配断言在Java流或所有非匹配结果

里克:

我有一个Validator它提供了一个接口isValid(Thing)方法,返回一个ValidationResult其中包含一个boolean和一个原因消息。

我想创建一个ValidatorAggregator该接口执行一个或多个的实施ValidatorS(如果有的话Validator返回一个积极的结果,那么结果是肯定的)。如果有任何验证成功,我想短路,就回到它的结果。如果没有验证成功,我想回到所有失败的消息。

我可以做到这一点简洁使用流findFirst().orElse(...),但使用这种模式我失去了所有的中间结果,如果findFirst返回空:

public ValidationResult isValid(final Thing thing) {
    return validators.stream()
      .map(v -> validator.isValid(thing))
      .filter(ValidationResult::isValid)
      .findFirst()
      .orElseGet(() -> new ValidationResult(false, "All validators failed'));
}

有什么办法来捕获失败的结果使用流,甚至小于下面只是更加简洁?

public ValidationResult isValid(final Thing thing) {
    final Set<ValidationResult> failedResults = new HashSet<>();
    for (Validator validator : validators) {
        final ValidationResult result = validator.isValid(thing);
        if (result.isValid()) {
            return result;
        }
        failedResults.add(result);
    }
    return new ValidationResult(false, "No successful validator: " + failedResults); 
    // (assume failedResults stringifies nicely)
}

编辑:根据意见,我同意我想要做的是不成熟的优化(尤其是当这些验证程序是非常轻巧)。我可能会用类似于计算所有验证,并划分为成功/失败的结果霍尔格的解决方案去的东西。

这被标记为愚弄的人你能拆分流分成两个流?partitioningBy答案排序是的,但我认为这个问题是问,并讨论应答,不同的问题。

霍尔格:

存在一个处理以同样的效率所有的情况下没有完美的解决方案。即使你的循环变体,其满足的是短路和处理验证只有一次的标准,有创造和填补这一可能变成只要有一个验证成功是不必要的集合的缺点。

选择取决于与运营,并具有至少一个验证成功的可能性相关联的实际成本。如果一般情况下得到最好的性能处理,就可能超过上罕见的案件的处理解决方案的处罚。

所以

// you may use this if the likelihood of a success is high; assumes
// reasonable costs for the validation and consists (repeatable) results
public ValidationResult isValid(final Thing thing) {
    return validators.stream()
      .map(v -> v.isValid(thing))
      .filter(ValidationResult::isValid)
      .findFirst()
      .orElseGet(() -> new ValidationResult(false, "All validators failed"
        + validators.stream().map(v -> v.isValid(thing)).collect(Collectors.toSet())));
}
// you may use this if the likelihood of a success is
// very low and/or you intent to utilize parallel processing
public ValidationResult isValid(final Thing thing) {
    Map<Boolean,Set<ValidationResult>> results = validators.stream()
        .map(v -> v.isValid(thing))
        .collect(Collectors.partitioningBy(ValidationResult::isValid, Collectors.toSet()));
    return results.get(true).stream().findAny()
        .orElseGet(() -> new ValidationResult(false,
                             "No successful validator: "+results.get(false)));
}
// if chances of successful validation are mixed or unpredictable
// or validation is so expensive that everything else doesn't matter
// stay with the loop
public ValidationResult isValid(final Thing thing) {
    final Set<ValidationResult> failedResults = new HashSet<>();
    for (Validator validator : validators) {
        final ValidationResult result = validator.isValid(thing);
        if (result.isValid()) {
            return result;
        }
        failedResults.add(result);
    }
    return new ValidationResult(false, "No successful validator: " + failedResults);
}

考虑列表进行排序,使之与成功的机会较高验证程序是在一开始...

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

仅在所有与第一个where子句匹配的行也与第二个匹配的情况下返回结果

正则表达式匹配器仅返回第一个结果

Lodash,循环调用函数并返回第一个匹配结果

如何仅返回XPath中的第一个匹配结果?

返回Java 8流中的第一个匹配项(类似于_.find)

从第一个匹配条件获取结果,不考虑下一个匹配条件的结果

LEFT JOIN返回第一个表的所有结果

猫鼬 $elemMatch 返回所有结果而不是第一个

DataFrame 游戏:返回与第一个较低或相等的日期时间匹配的所有记录

PyQuery-attr match仅返回第一个匹配项,而不是所有匹配项

Group by使用pymongo仅返回mongodb中的第一个匹配文档,如何检索所有匹配的文档?

Select2 4.0.1:如何仅返回第一个字符匹配的结果?

全球匹配仅返回第一个匹配

数组的整数子集的和,获取所有结果而不是第一个结果

UISearchController仅返回第一个结果,但Core Data有多个结果

从匹配位置替换所有匹配的字符串,直到第一个'符号

awk找到第一个匹配项,而不是所有匹配项

如何替换除第一个匹配项外的所有匹配字符

为什么posix c中的regexec()总是返回第一个匹配项,如何返回所有匹配位置只运行一次?

在PHP中返回第一个非空函数结果的快捷方式

从Pool.async_map返回第一个非零结果

如何转换for循环以查找Java流中的第一个匹配项?

如何过滤出不匹配在Java顺序流的谓词的第一个元素?

JsonReader仅返回第一个结果

要求返回第一个结果的嵌套查询

Javascript数组的第一个结果返回“空”

Foreach循环仅返回第一个结果

Django __in,但返回第一个匹配的元素

返回第一个匹配的行