据我所知,求和 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()
和 Double.max()
.今后,我一定会在 List<Double>
上使用此成语进行此类操作。和类似的。
最佳答案
Is there some way to squeeze autoboxing in to make this shorter?
是的,有。你可以简单地写:
double sum = vals.stream().mapToDouble(d->d).sum();
这使得拆箱变得隐含,但当然不会提高效率。
由于List
被装箱,拆箱是不可避免的。另一种方法是:
double sum = vals.stream().reduce(0.0, Double::sum);
它不执行 mapToDouble
但仍允许将代码读取为“... sum”。
关于java - mapToDouble() 是否真的需要将 List<Double> 与 Java 8 流相加?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24421140/