使用流处理原始数据类型及其对应的包装类

22

在尝试使用Java8的Streams-API时,我遇到了以下问题:

要将一个原始包装类对象数组转换为Stream,我只需要调用Stream.of(array)。但是,要将原始数据类型的数组转换为Stream,我必须从相应的包装器(类)流类中调用.of(array)(这听起来很傻)。

例如:

final Integer[] integers = {1, 2, 3};
final int[]     ints     = {1, 2, 3};


Stream.of(integers).forEach(System.out::println); //That works just fine

Stream.of(ints).forEach(System.out::println);     //That doesn't

IntStream.of(ints).forEach(System.out::println);  //Have to use IntStream instead


我的问题: 为什么会这样?这是否与例如Arrays.asList()的行为相对应,它也仅适用于包装类数组?


4
使用IntStream方法处理IntStreams,使用Stream方法处理Streams难道不是很正常吗? - JB Nizet
5
您还可以使用Arrays.stream(ints).forEach(System.out::println) - skiwi
@skiwi 非常高兴知道这个。谢谢。 - ifloop
1
与https://dev59.com/Fm7Xa4cB1Zd3GeqPpWnN相关,但不是直接的副本。 - Honza Zidek
1个回答

29

Java 8的流框架有一个通用的Stream<T>,用于将对象作为元素,还有三种原始类型的流:IntStreamLongStreamDoubleStream。 如果您使用原始类型,请使用后者之一,在您的情况下使用IntStream

看这张图片:

enter image description here

背后的原理是:

  1. Java泛型不能使用原始类型:只能有List<Integer>Stream<Integer>,而没有List<int>Stream<int>

  2. 当引入Java集合时,仅针对类进行了引入,因此如果您想要int列表,则必须将它们(每个单个元素!)包装到Integer中。这很耗费资源!

  3. 当引入Java Streams时,他们决定绕过这种开销,并且“类导向”的流(使用通用机制)一起并行引入了三组额外的所有库函数,专门为最重要的原始类型设计:intlongdouble

顺便提一下,他们在 java.util.function 包中预定义的函数接口也进行了相同的处理,因此您有 PredicateIntPredicateDoublePredicateLongPredicate

此外,在这里还可以看到一个精彩的解释:https://dev59.com/vWAh5IYBdhLWcg3wBPXY#22919112


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接