Java 8 Streams - 为什么我不能对整数流求和?

Rob*_*roj 6 java java-8 java-stream

给出一个Integer列表: List<Integer> numbers = Arrays.asList(1,2,3);

为什么我不能总结他们:numbers.stream().sum();

相反,我必须这样做: numbers.stream().mapToInt(e -> e).sum();

我知道mapToInt产生一种IntStream原始的专业化.但我仍然没有得到它.为什么它不能和整数相加?我知道这个列表有整数,编译器也应该能够做到这一点.毕竟它现在可以推断lambda表达式中的类型参数.

好的,一个Integer可能为null,sum也会失败.但我可以对此负责并过滤掉null:

numbers.stream().filter(Objects::nonNull).sum();

为什么我不能总结整数流?

rge*_*man 15

调用stream()一个List将获得一个通用的Stream,它可以处理任何引用类型,而不仅仅是数字类型.包含sum方法没有意义Stream,因为对URLs,Classes,Threads或任何其他非数字引用类型求和没有意义.

您可以通过调用reduce以下方式对元素求和

numbers.stream().reduce(0, (a, b) -> a + b)
Run Code Online (Sandbox Code Playgroud)

但这将涉及很多拆箱和拳击.最好通过将它们转换为a IntStream,对ints 进行操作并调用sum()(或者summaryStatistics()包括count,average,max和min以及sum)来对它们进行求和.

你甚至可以使用IntStream.of并避免装箱值甚至一次.

IntStream.of(1, 2, 3).sum()
Run Code Online (Sandbox Code Playgroud)

  • @Eugene`mapToInt`版本实际上是最好的,因为它不会打包和取消所有中间总和. (4认同)
  • @Andreas或`.collect(Collectors.summingInt(i - > i))`,这也避免了拳击操作. (4认同)
  • 用方法引用替换lambda:`numbers.stream().reduce(0,Math :: addExact)`*(溢出时失败)*---或者,取消装入`Integer`值:`numbers.stream().mapToInt (号::的intValue)的.sum()` (2认同)