Given a list of Integer's: List<Integer> numbers = Arrays.asList(1,2,3);
给出一个Integer的列表:List
Why can't I sum them like: numbers.stream().sum();
?
为什么我不能总结它们:numbers.stream()。sum();?
Instead I have to do this: numbers.stream().mapToInt(e -> e).sum();
相反,我必须这样做:numbers.stream()。mapToInt(e - > e).sum();
I know that mapToInt
produces an IntStream
, the primitive specialization. But still I don't get it. Why can't it sum Integers? I know that this list has Integers and the compiler should be able to do the same. After all it can now infer type parameters in lambda expressions.
我知道mapToInt生成一个IntStream,即原始特化。但我仍然没有得到它。为什么它不能和整数相加?我知道这个列表有整数,编译器也应该能够做到这一点。毕竟它现在可以推断lambda表达式中的类型参数。
OK, an Integer could be null and sum would fail. But I could take responsibility for that and filter null out:
好的,一个Integer可能为null,sum也会失败。但是我可以对此负责并过滤掉null:
numbers.stream().filter(Objects::nonNull).sum();
。numbers.stream()滤波器(对象::非空)的.sum();
Why can't I sum a Stream of Integers?
为什么我不能总结整数流?
4 个解决方案
#1
14
Calling stream()
on a List
will get you a general-purpose Stream
, which can handle any reference type, not just numeric types. It doesn't make sense to include a sum
method on Stream
, because it doesn't make sense to sum URL
s, Class
es, Thread
s, or any other non-numeric reference type.
在List上调用stream()将为您提供通用Stream,它可以处理任何引用类型,而不仅仅是数字类型。在Stream上包含sum方法没有意义,因为对URL,Classes,Threads或任何其他非数字引用类型求和没有意义。
You could sum the elements by calling reduce
:
您可以通过调用reduce来对元素求和:
numbers.stream().reduce(0, (a, b) -> a + b)
But that would involve a lot of unboxing and boxing. It would be best to sum them as you have it, by converting it to an IntStream
, which operates on int
s, and calling sum()
(or summaryStatistics()
, which includes count, average, max, and min along with sum).
但这将涉及很多拆箱和拳击。通过将它转换为对int进行操作的IntStream,并调用sum()(或summaryStatistics(),其中包括count,average,max和min以及sum),最好将它们与它一起求和。
You could even use IntStream.of
and avoid boxing the values even once.
你甚至可以使用IntStream.of并避免装箱值甚至一次。
IntStream.of(1, 2, 3).sum()
#2
3
You cannot do:
你做不到:
numbers.stream().sum();
because Stream<T>
is a generic type and as far as it's concerned it's dealing with any type of object. e.g. that could be Stream<Person>
, Stream<Apple>
etc. hence doesn't make sense to include a sum
method.
因为Stream
#3
3
Stream<Interger>
and IntStream
are actually different. As numbers.stream()
returns an object of Type Stream
and Stream
interface does not have any method like sum
. Another side numbers.stream().mapToInt(e -> e)
returns IntStream
which has the sum
method.
Stream
#4
2
I think that what you are asking for can not be done at all, even theoretically.
我认为你要求的东西根本无法完成,甚至理论上也是如此。
I mean stream()
is declared on the List
interface and it returns Stream<E>
. You know that E
is actually an Integer
, the compiler has to infer that, and it's not like the compiler can change the return type when it infers the type, you are still going to get a general Stream<E>
.
我的意思是在List接口上声明了stream(),它返回Stream
But this is even worse if I think about it more, in such a case there would have to be a BaseStream
returned that both Stream<String>
and IntStream
would extend, and sum
for a Stream<String>
makes no sense. Later E
type would have to be preserved at runtime, so that you know what specialization to return and this is obviously not possible (well not without a useless witness that is)
但是如果我更多地考虑它会更糟,在这种情况下,必须返回一个BaseStream,Stream
If there were a IntsList
that a theoretical IntsArray.asIntsList
would return, this would have been indeed possible, but what a mess this would become in such a case.
如果有一个理论上的IntsArray.asIntsList会返回IntsList,那么这确实是可能的,但在这种情况下会变得多么混乱。
#1
14
Calling stream()
on a List
will get you a general-purpose Stream
, which can handle any reference type, not just numeric types. It doesn't make sense to include a sum
method on Stream
, because it doesn't make sense to sum URL
s, Class
es, Thread
s, or any other non-numeric reference type.
在List上调用stream()将为您提供通用Stream,它可以处理任何引用类型,而不仅仅是数字类型。在Stream上包含sum方法没有意义,因为对URL,Classes,Threads或任何其他非数字引用类型求和没有意义。
You could sum the elements by calling reduce
:
您可以通过调用reduce来对元素求和:
numbers.stream().reduce(0, (a, b) -> a + b)
But that would involve a lot of unboxing and boxing. It would be best to sum them as you have it, by converting it to an IntStream
, which operates on int
s, and calling sum()
(or summaryStatistics()
, which includes count, average, max, and min along with sum).
但这将涉及很多拆箱和拳击。通过将它转换为对int进行操作的IntStream,并调用sum()(或summaryStatistics(),其中包括count,average,max和min以及sum),最好将它们与它一起求和。
You could even use IntStream.of
and avoid boxing the values even once.
你甚至可以使用IntStream.of并避免装箱值甚至一次。
IntStream.of(1, 2, 3).sum()
#2
3
You cannot do:
你做不到:
numbers.stream().sum();
because Stream<T>
is a generic type and as far as it's concerned it's dealing with any type of object. e.g. that could be Stream<Person>
, Stream<Apple>
etc. hence doesn't make sense to include a sum
method.
因为Stream
#3
3
Stream<Interger>
and IntStream
are actually different. As numbers.stream()
returns an object of Type Stream
and Stream
interface does not have any method like sum
. Another side numbers.stream().mapToInt(e -> e)
returns IntStream
which has the sum
method.
Stream
#4
2
I think that what you are asking for can not be done at all, even theoretically.
我认为你要求的东西根本无法完成,甚至理论上也是如此。
I mean stream()
is declared on the List
interface and it returns Stream<E>
. You know that E
is actually an Integer
, the compiler has to infer that, and it's not like the compiler can change the return type when it infers the type, you are still going to get a general Stream<E>
.
我的意思是在List接口上声明了stream(),它返回Stream
But this is even worse if I think about it more, in such a case there would have to be a BaseStream
returned that both Stream<String>
and IntStream
would extend, and sum
for a Stream<String>
makes no sense. Later E
type would have to be preserved at runtime, so that you know what specialization to return and this is obviously not possible (well not without a useless witness that is)
但是如果我更多地考虑它会更糟,在这种情况下,必须返回一个BaseStream,Stream
If there were a IntsList
that a theoretical IntsArray.asIntsList
would return, this would have been indeed possible, but what a mess this would become in such a case.
如果有一个理论上的IntsArray.asIntsList会返回IntsList,那么这确实是可能的,但在这种情况下会变得多么混乱。