mapToDouble()是否真的需要将List <double>与Java 8流相加?</double>

时间:2014-06-26 01:34:07

标签: java java-8 java-stream

据我所知,使用Java 8流汇总List<Double>的方法是:

List<Double> vals = . . . ;
double sum = vals.stream().mapToDouble(Double::doubleValue).sum();

对我而言,mapToDouble(Double::doubleValue)似乎有些苛刻 - 只是那种样板式的仪式&#34;仪式&#34;应该放弃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>和类似的情况下使用这个成语进行此类操作。

3 个答案:

答案 0 :(得分:46)

  

有没有办法挤压自动装箱以缩短它?

是的,有。你可以简单地写一下:

double sum = vals.stream().mapToDouble(d->d).sum();

这使得取消装箱是隐含的,但当然不会增加效率。

由于List 已装箱,因此取消装箱是不可避免的。另一种方法是:

double sum = vals.stream().reduce(0.0, Double::sum);

它不会执行mapToDouble但仍允许将代码读作“... sum”。

答案 1 :(得分:31)

  

对我而言,mapToDouble(Double::doubleValue)似乎[lambda]和溪流应该放弃。

使用mapToDouble的需要是决定通过类型擦除来实现泛型的结果,基本上关闭了在泛型中使用原语的任何可能性。正是这一决定使得有必要创建DoubleStreamIntStreamLongStream系列类 - 以提供基于流的拆箱。

  

有没有办法挤压自动装箱以缩短它?或者这只是当前最先进的技术状态?

不幸的是,目前还没有:虽然理论上编译器可以理解Stream<Double>可以隐式地转换为DoubleStream,但是与基元未拆箱的方式相同,没有完成。

就基于阵列的解决方案而言,它是三者中效率最高的解决方案。但是,它不像其他两个那样灵活:mapToDouble允许您对自定义类的任何属性求和,而最后一个允许您执行其他类型的聚合。

  

reduce(....)sum()

长得多

我同意,就可读性而言,这种方法比mapToDouble差。

答案 2 :(得分:5)

这是另一种方法。如果您只需要DoubleIntegerLong列表中的总和,平均值,最小值,最大值等,则可以使用其中一个Collectors,例如:

List<Double> doubles = Arrays.asList(3.14, 5.15, 4.12, 6.);
System.out.println(
        doubles.stream()
                .collect(Collectors.summingDouble(d -> d))
);

会打印 18.41

注意,方法名称是 summingDouble ,还有另一个名为 summarizingDouble 的方法,它返回DoubleSummaryStatistics,包含所有基本的数学运算结果。