mapToDouble()对列表求和是否真的必要 Java 8流?
据我所知,List<Double>
使用Java 8流求和的方法是:
List<Double> vals = . . . ;double sum = vals.stream().mapToDouble(Double::doubleValue).sum();
在我mapToDouble(Double::doubleValue)
看来,这似乎有些cru琐-只是应该放弃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>
。
回答:
在我
mapToDouble(Double::doubleValue)
看来,似乎不需要什么lambda和小溪。
使用的需要mapToDouble
是决定通过类型擦除实现泛型的结果,实质上是在使用泛型内部使用基元的任何可能性上都关了门。这是使得有必要创建相同的决定DoubleStream
,IntStream
和LongStream
家庭类-
提供基于流的拆箱。
有什么方法可以压缩自动装箱以使其更短吗?还是这只是当前的最新状态?
不幸的是,目前还没有:尽管从理论上说编译器有可能找出Stream<Double>
可以DoubleStream
隐式转换为原始类型的方法,但是尚未完成。
就基于阵列的解决方案而言,它是这三种方法中效率最高的。但是,它不如其他两个灵活:一个mapToDouble
可以让您对自定义类的任何属性求和,而最后一个可以让您执行其他类型的聚合。
reduce(....)
比这更长sum()
我同意,这种方法比mapToDouble
可读性差。
以上是 mapToDouble()对列表求和是否真的必要 Java 8流? 的全部内容, 来源链接: utcz.com/qa/433284.html