AFAIK对BigDecimal
流进行求和的唯一方法是:
BigDecimal result = stream.reduce(BigDecimal.ZERO, BigDecimal::add);
这里的问题是每次调用BigDecimal::add
都会创建一个新的BigDecimal
,而不是更改一个可变类型。
Collector
是否有Stream<BigDecimal>
的可变减少操作?
答案 0 :(得分:5)
BigDecimal:&#34;不可变,任意精度的带符号十进制数。&#34;
由于它是不可变的,因此没有方法可以在不创建新对象的情况下操纵它们。任何能够做到这一点的方法都会破坏类的保证(比如BigDecimal.ZERO为0)
答案 1 :(得分:4)
嗯,没有公共可变BigDecimal
个伴侣类,因此没有Collector
使用它。但是,除非分析工具告诉您存在问题,否则您不应该担心实例创建的性能影响。
像HotSpot这样的现代JVM通常善于处理在热循环中创建的临时对象。即使他们无法忽视分配,分配成本也不会那么大。这与例如不同。 String::concat
其中实例创建成本不仅包括分配,而且复制先前创建的String
实例的全部内容,产生这种减少的二次时间复杂度(除非优化器设法重写此类代码)。同样适用于通过纯(不可变)减少产生Collection
的尝试。
这可能与IntStream
,LongStream
和DoubleStream
等原始类型专精的存在相矛盾,但这是一种权衡。通常,JRE开发人员的偏好是改进JVM性能(为了所有值类型),而不是为每个不可变类添加可变辅助类。在完全值类型支持的到来之前,可能存在对原始类型的特殊支持的连续性,但是不要期望为不可变类型添加新的公共可变伴随类(除非我们在讨论{{中的建设成本) 1}}例子。。