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:
inbound
is the base case. For example, ifvalidators
is an empty list, it is the object that is returned by default(toValidate, validator) -> validator.validate(toValidate, holder, product)
it takes anItem
and avalidator
and produces anItem
. This happens via thevalidate()
method on the validator.(prev, next) -> next
defines how reduction should happen between two items – you need to pick one. In yourfor
-loop you are always overwritingtoValidate
with 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 ); }