如何在使用 Stream API 的函数更改字符串变量的同时跟踪它?

How to keep track of a String variable while changing it with Functions using Stream API?

我想使用 Stream API 在使用函数更改变量时跟踪变量。

我的代码:

public String encoder(String texteClair) {
    for (Crypteur crypteur : algo) {
        texteClair = crypteur.encoder(texteClair);
    }
    return texteClair;
}

我有一个包含方法的 类 列表,我想在所有方法中放入一个变量,就像上面的代码所做的那样。

它工作得很好,但我想知道如何用流来完成它?

我们可以使用 reduce() 吗?

使用 AtomicReference,它 最终有效 ,但它的包装值可能会改变:

public String encoder(String texteClair) {
    AtomicReference<String> ref = new AtomicReference<>(texteClair);
    algo.stream().forEach(c -> ref.updateAndGet(c::encoder)); // credit Ole V.V
    return ref.get();
}

Could we use reduce()?

我想我们可以。但请记住,使用流并不是最好的情况。

因为你提到了 "classes" 的复数形式,我假设 Crypteur 是一个 抽象 class 接口 。作为一般规则,您应该更喜欢 interfaces 而不是 abstract classes,所以我假设 Crypteur 是一个接口(如果不是,那不是什么大问题)并且它至少有一个类似于此的实现:

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);
    }
}

然后您可以像这样将编码器与流一起使用:

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(); });
}

注意 combiner,它在parallel中用于组合部分结果,故意抛出一个exception 表示此任务不可并行化。所有转换都必须按顺序应用,例如,我们不能在给定字符串上应用一些编码器,然后在给定字符串上单独应用其余编码器并合并两个结果 - 这是不可能的。

输出

EVERYPIECEOFKNOWLEDGEMUSTHWVEWSINGLEUNWMBIGUOUSWUTHORITWTIVEREPRESENTWTIONWITHINWSYSTEM