最佳答案
据我所知,使用 Java8流对 List<Double>
求和的方法是这样的:
List<Double> vals = . . . ;
double sum = vals.stream().mapToDouble(Double::doubleValue).sum();
在我看来,mapToDouble(Double::doubleValue)
似乎有点难以驾驭——只是那种 Lambdas 和 stream 应该摒弃的样板“仪式”。
最佳实践告诉我们,与数组相比,我们更喜欢 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>
等类似的操作中使用这个习惯用法。