据我所知,求和的方法List<Double>
使用 Java 8 流是这样的:
List<Double> vals = . . . ;
double sum = vals.stream().mapToDouble(Double::doubleValue).sum();
对我来说,mapToDouble(Double::doubleValue)
看起来有点粗糙——正是 lambda 和流应该放弃的那种样板“仪式”。
最佳实践告诉我们更喜欢List
数组上的实例,但对于这种求和,数组看起来更干净:
double[] vals = . . . ;
double sum = Arrays.stream(vals).sum();
当然,人们可以这样做:
List<Double> vals = . . . ;
double sum = vals.stream().reduce(0.0, (i,j) -> i+j);
但那个reduce(....)
比sum()
.
我知道这与需要围绕 Java 的非对象原语改造流的方式有关,但是,我是否在这里遗漏了一些东西?有什么方法可以压缩自动装箱以使其更短吗?或者这只是当前的技术水平?
更新 - 答案摘要
以下是答案摘要。虽然我在这里有一个总结,但我敦促读者自己仔细阅读答案。
@dasblinkenlight 解释说,由于 Java 历史上更早做出的决定,某种类型的拆箱总是必要的,特别是泛型的实现方式及其与非对象基元的关系。他指出,理论上编译器可以凭直觉进行拆箱并允许更简短的代码,但这尚未实现。
@Holger 展示了一个非常接近我所询问的表达能力的解决方案:
double sum = vals.stream().reduce(0.0, Double::sum);
我不知道新的静电Double.sum()
方法。添加了 1.8,它似乎就是为了我所描述的目的而设计的。我还发现Double.min()
and Double.max()
。展望未来,我肯定会使用这个习惯用法来进行此类操作List<Double>
和类似的。