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

时间:2018-07-16 18:14:54

标签: java java-8 java-stream

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

我为什么不能像numbers.stream().sum();那样概括它们?

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

我知道mapToInt会产生IntStream(原始专业化)。但是我还是不明白。为什么不能对整数求和?我知道此列表具有Integers,并且编译器应该能够执行相同操作。毕竟,它现在可以推断lambda表达式中的类型参数。

好的,一个Integer可以为null,并且求和将失败。但是我可以对此负责并过滤掉null:

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

为什么我不能对整数流求和?

4 个答案:

答案 0 :(得分:14)

stream()上调用List将为您提供通用的Stream,它可以处理任何引用类型,而不仅仅是数字类型。在sum上包含Stream方法是没有意义的,因为将URLClassThread之和相加是没有意义的s或任何其他非数字引用类型。

您可以通过调用reduce对元素求和:

numbers.stream().reduce(0, (a, b) -> a + b)

但这将涉及大量拆箱和装箱。最好对它们进行求和,方法是将其转换为IntStream上运行的int,然后调用sum()(或summaryStatistics(),其中包括计数,平均值,最大值和最小值以及总数)。

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

IntStream.of(1, 2, 3).sum()

答案 1 :(得分:3)

Stream<Interger>IntStream实际上是不同的。当numbers.stream()返回类型为Stream的对象时,Stream接口没有像sum这样的方法。另一面numbers.stream().mapToInt(e -> e)返回具有IntStream方法的sum

答案 2 :(得分:3)

您不能这样做:

numbers.stream().sum();

因为Stream<T>是泛型类型,就其而言,它正在处理任何类型的对象。例如可能是Stream<Person>Stream<Apple>等,因此没有必要包含sum方法。

答案 3 :(得分:2)

我认为您的要求根本无法完成,即使从理论上讲也是如此。

我的意思是stream()List接口上声明,并且返回Stream<E>知道E实际上是Integer,编译器必须推断,这不像编译器可以在以下情况下更改返回类型它可以推断出类型,您仍将获得通用的Stream<E>

但是,如果我考虑得更多,那就更糟了,在这种情况下,必须返回BaseStreamStream<String>都将延伸的IntStream,而{{ 1}}对于sum没有任何意义。以后的Stream<String>类型将必须在运行时保留,这样您就知道要返回什么专业化,这显然是不可能的(当然,如果没有无用的见证人,也是不可能的)

如果有一个E会返回理论上的IntsList,这确实是可能的,但是在这种情况下会变得一团糟。