Could we use reduce()
?
I guess we could. But keep in mind that it's not the best case to use streams.
Because you've mentioned "classes" in plural, I assume that Crypteur
is either an abstract class or an interface. As a general rule you should favor interfaces over abstract classes, so I'll assume the that Crypteur
is an interface (if it's not, that's not a big issue) and it has at least one implementation similar to this :
public interface Encoder {
String encoder(String str);
}
public class Crypteur implements Encoder {
private UnaryOperator<String> operator;
public Crypteur(UnaryOperator<String> operator) {
this.operator = operator;
}
@Override
public String encoder(String str) {
return operator.apply(str);
}
}
Then you can utilize your encoders with stream like this:
public static void main(String[] args) {
List<Crypteur> algo =
List.of(new Crypteur(str -> str.replaceAll("\\p{Punct}|\\p{Space}", "")),
new Crypteur(str -> str.toUpperCase(Locale.ROOT)),
new Crypteur(str -> str.replace('A', 'W')));
String result = encode(algo, "Every piece of knowledge must have a single, unambiguous, authoritative representation within a system");
System.out.println(result);
}
public static String encode(Collection<Crypteur> algo, String str) {
return algo.stream()
.reduce(str,
(String result, Crypteur encoder) -> encoder.encoder(result),
(result1, result2) -> { throw new UnsupportedOperationException(); });
}
Note that combiner
, which is used in parallel to combine partial results, deliberately throws an exception to indicate that this task ins't parallelizable. All transformations must be applied sequentially, we can't, for instance, apply some encoders on the given string and then apply the rest of them separately on the given string and merge the two results - it's not possible.
Output
EVERYPIECEOFKNOWLEDGEMUSTHWVEWSINGLEUNWMBIGUOUSWUTHORITWTIVEREPRESENTWTIONWITHINWSYSTEM