Stream / Reduce 应用于具有绑定变量的输入值的一系列函数 Java

Stream / Reduce a series of functions applied to an input value with bound variables in Java

如何使用流重写这个循环。

private final List<RegionSpecificValidator> validators;
public Item applyValidations(Item inbound, Holder holder, Product product) {
    Item toValidate = inbound;
    for (var validator: validators)
        toValidate = validator.validate(toValidate, holder, product);
    return toValidate;
}

应该可以使用 validators.stream().reduce(...)

重写这个循环

我已经尝试使用此处的指南,但我无法弄清楚需要实现什么 BiFunction 接口以及如何实现。
当前的界面如下所示:

public interface RegionSpecificValidator {
    Item validate(Item toValidate, Holder holder, Product product);
}

我看过这个指南:Reducing a list of UnaryOperators in Java 8
然而,我不清楚在这种情况下我是如何实现 andThen 的,或者即使它是可能的。

您需要使用reduce() method with transformer and combiner

三个参数如下:

  • inbound 是基本情况。例如,如果 validators 是一个空列表,则它是默认 returned 的对象
  • (toValidate, validator) -> validator.validate(toValidate, holder, product) 它需要一个 Item 和一个 validator 并产生一个 Item。这是通过验证器上的 validate() 方法发生的。
  • (prev, next) -> next 定义两个项目之间应如何减少 - 您需要选择一个。在你的 for 循环中,你总是用新值覆盖 toValidate,所以在这种情况下我们应该 return next,即我们从 [= 获得的最后一个元素22=].
public Item applyValidations(Item inbound, Holder holder, Product product) {
    return validators.stream().reduce(
        inbound, 
        (toValidate, validator) -> validator.validate(toValidate, holder, product), 
        (prev, next) -> next
    );
}

您还可以使用如下方式将所有验证器缩减为一个:

RegionSpecificValidator validator = validators.stream().reduce(
    (i, h, p) -> i,
    (a, b) -> (i, h, p) -> b.validate(a.validate(i, h, p), h, p)
);
  • (i, h, p) -> i:初始验证器,只是returns输入项。需要,因为单个参数 reduce() 方法 returns 和 Optional 而我们不希望在此处使用。
  • (a, b) -> (i, h, p) -> b.validate(a.validate(i, h, p), h, p):写出来,可能更有意义:
    (a, b) -> {                         // `a` and `b` are both validators
        return (i, h, p) -> {           // create a new implementation of the validator interface
            i = a.validate(i, h, p);    // the result from `a` will be saved 
            return b.validate(r, h, p); // and then passed to `b`
        }
    }
    
    此代码将两个验证器“合并”在一起,将参数应用于第一个验证器,然后使用返回的 Item 作为要传递给下一个验证器的参数。然后将它们都包装在 RegionSpecificValidator 类型的 lambda 中。请注意,这仅在 RegionSpecificValidator 是功能接口时才有效。 (在interface中只有一个abstract方法)

这也可以只做一次(iff validators 是不可变的并且在 class' 创建时给出):

private final RegionSpecificValidator validator;

public YourClass(List<Validator> validators) {
    this.valdiator = validators.stream().reduce(
        (i, h, p) -> i,
        (a, b) -> (i, h, p) -> b.validate(a.validate(i, h, p), h, p)
    );
}

public Item applyValidations(Item inbound, Holder holder, Product product) {
    return validator.validate(inbound, holder, product);
}