如何在java 1.8中的reduce方法中使用StringBuilder?

Klo*_*ose 2 java string stringbuilder java-8 java-stream

String s = "apples for you";
StringBuilder returnString = new StringBuilder("");
Arrays.stream(s.split(" "))
        .reduce(returnString, (acc, str) -> acc.append(str.charAt(0)));
Run Code Online (Sandbox Code Playgroud)

预期输出每个单词的第一个字母,即afy

但在acc.append,处出现错误acc被视为 a String

ern*_*t_k 5

您的使用reduce不正确。您打算调用的重载是具有 3 个参数的重载,它还应该采用二元运算符StringBuilder

StringBuilder returnString = Arrays.stream(s.split(" "))
        .reduce(new StringBuilder(""), 
                (acc, str) -> acc.append(str.charAt(0)), 
                (sb1, sb2) -> sb1.append(sb2));
Run Code Online (Sandbox Code Playgroud)

如果您要在并行流上使用它,请执行可变缩减(使用stream.collect),因为初始身份字符串构建器对象可能会从多个线程不可预测地附加到:

StringBuilder returnString = Arrays.stream(s.split(" "))
        .collect(StringBuilder::new, 
                 (acc, str) -> acc.append(str.charAt(0)), 
                 StringBuilder::append);
Run Code Online (Sandbox Code Playgroud)

  • 这仍然是不正确的,因为它正在修改身份值。这将与并行流中断。或者,将“String.concat”与“reduce”一起使用,或者将“collect”与“StringBuilder”一起使用(这将免费为您提供“joining()”)。这是尝试执行[可变缩减](https://docs.oracle.com/en/java/javase/15/docs/api/java.base/java/util/stream/package-summary.html# MutableReduction)并且必须为此使用正确的方法。 (3认同)