How does one go about rewriting this loop using a stream.
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;
}
It should be possible to rewrite this loop using validators.stream().reduce(...)
I have tried using the guidance here, but I cannot figure out what BiFunction interface needs to be implemented and how.
The interface as it currently stands looks like this:
public interface RegionSpecificValidator {
Item validate(Item toValidate, Holder holder, Product product);
}
I have looked at this guidance: Reducing a list of UnaryOperators in Java 8
However it’s not clear how I implement andThen in this case, or even if it’s possible.
Advertisement
Answer
You need to use the reduce() method with transformer and combiner.
The three arguments are as follows:
inboundis the base case. For example, ifvalidatorsis an empty list, it is the object that is returned by default(toValidate, validator) -> validator.validate(toValidate, holder, product)it takes anItemand avalidatorand produces anItem. This happens via thevalidate()method on the validator.(prev, next) -> nextdefines how reduction should happen between two items – you need to pick one. In yourfor-loop you are always overwritingtoValidatewith the new value, so in this case we should returnnext, i.e. the last element that we obtained fromvalidator.validate().
public Item applyValidations(Item inbound, Holder holder, Product product) {
return validators.stream().reduce(
inbound,
(toValidate, validator) -> validator.validate(toValidate, holder, product),
(prev, next) -> next
);
}