在减少操作中使用StringBuilder(...)作为标识值会产生不可预测的结果

neerajdorle:

问题很简单:为什么我们不能中的操作中使用StringBuilder(...)as ,而可以将其用作??identity functionreduce(...)java8string1.concat(string2)identity function

string1.concat(string2)可以被视为类似于builder.append(string)(尽管据了解,这些操作之间几乎没有差异),但是我无法理解reduce操作中的差异。考虑以下示例:

  List<String> list = Arrays.asList("1", "2", "3"); 
  
  // Example using the string concatenation operation
  System.out.println(list.stream().parallel()
            .reduce("", (s1, s2) -> s1 + s2, (s1, s2)->s1 + s2));

  // The same example, using the StringBuilder
  System.out.println(list.stream() .parallel()
            .reduce(new StringBuilder(""), (builder, s) -> builder
                    .append(s),(builder1, builder2) -> builder1
                    .append(builder2)));
 
 // using the actual concat(...) method
 System.out.println(list.stream().parallel()
            .reduce("", (s1, s2) -> s1.concat(s2), (s1, s2)->s1.concat(s2)));

这是执行上述几行后的输出:

 123
 321321321321   // output when StringBuilder() is used as Identity
 123

builder.append(string)按原样str1.concat(str2)一个关联操作那为什么能concat工作append却没有呢?

清扫器:

是的,append 确实的关联,但这并不是由于储液器和组合传递函数的唯一要求。根据文档,它们必须是:

  • 联想的
  • 无干扰
  • 无状态

append不是无国籍的。这是有状态的当你这样做sb.append("Hello"),它不仅返回一个StringBuilderHello追加到末尾,它也改变了内容的(即状态) sb

另外从文档

如果流操作的行为参数是有状态的,则流管道结果可能不确定或不正确。有状态的lambda(或其他实现适当功能接口的对象)是一种有状态的lambda,其结果取决于在流管道执行期间可能更改的任何状态。

同样由于这个原因new StringBuilder(),一旦应用了累加器或组合器,它就不是有效的标识。空字符串生成器中将添加一些内容,并且所有身份必须满足的以下方程式不再满足:

combiner.apply(u, accumulator.apply(identity, t)) == accumulator.apply(u, t)

并行流有可能在调用累加器和/或组合器之后使用旧的字符串生成器,并期望它们的内容不会更改。但是,累加器和组合器会使字符串生成器发生变异,从而导致流产生不正确的结果。

另一方面,concat满足上述所有三个条件。它是无状态的,因为它不会更改调用它的字符串。它只是重新调整了一个新的串联字符串。String反正是不变的,不能更改:D)

无论如何,这是一个可变还原的用例collect

System.out.println((StringBuilder)list.stream().parallel()
    .collect(
        StringBuilder::new, 
        StringBuilder::append, 
        StringBuilder::append
    )
);

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

删除指定的操作会产生不可预测的结果

减少并行流的返回不可预测的结果

使用 "%" 操作会产生意外结果

尝试在具有GMP的C ++上使用RSA解密文件会产生无法预测的结果

使用没有OrderBy和filter的First / FirstOrDefault / Last / LastOrDefault操作可能会导致不可预测的结果

从uchar *转换为uint *会产生不可预测的结果

使用 ETS 进行预测会产生意想不到的恒定值

在Java中使用StringBuffer和StringBuilder作为方法返回类型

操作员的结果-未使用迅速减少

在MATLAB中使用均值函数会产生不同的结果

在Julia中使用@time会产生令人惊讶的结果

在C中使用unsigned会产生负的临时结果

在JIT中使用全局变量会产生垃圾结果

尝试在别名中使用`pwd`会产生意外结果

在操作中使用IActionResult作为结果类型的优势

为什么在减法中使用不一致的结果会减少?

使用Emgu C#获取RGB的色相(HSV / HSB)值会产生错误的结果

在C#中使用“值”作为标识符

在 lambda 表达式中使用 StringBuilder.Append() 会产生一个空字符串

在Python中使用XGboost_Regressor会产生很好的训练效果,但预测效果很差

在Python中使用列表作为值的操作搜索字典

在for循环中使用random会产生奇怪的值

如何使用线性回归模型产生单个预测值?

使用字典替换NumPy数组中的值会产生模棱两可的结果,为什么呢?

在JAVA中使用重新配置获取不同的结果StringBuilder vs String

减少字典值的并集会产生意外结果

翻转操作数时,使用空对象添加空数组会产生不同的结果

使用char **指针的字符串操作代码会产生意外结果

在excel中使用MATCH函数的结果作为单元格标识符