将流与基元数据类型和相应的包装器一起使用

在玩Java8的Streams-API时,我偶然发现了以下内容:

要将原始包装器classe对象数组转换为I,我只需要调用.但是要转换基元数据类型的数组,我必须从相应的包装器(类)流类调用(< - 这听起来很愚蠢)。StreamStream.of(array).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()


答案 1

Java 8 流框架有一个通用的用于对象作为元素,以及三个原始流 ,用于主要的三个基元。如果您使用基元,请使用后一种,在您的情况下。Stream<T>IntStreamLongStreamDoubleStreamIntStream

见图:

enter image description here

背后是:

  1. Java 泛型不能与基元类型一起使用:可以只有 和 ,但不能有 List<int>Stream<int>List<Integer>Stream<Integer>

  2. Java Collections框架被引入时,它只为类引入,所以如果你想有一个s,你必须把它们(每个元素!)包装到s。这是昂贵的!ListintInteger

  3. Java Streams框架被引入时,他们决定绕过这个开销,并与“面向类”的流并行(使用泛型机制),他们引入了三个额外的所有库函数集,专门为最重要的基元类型设计:,,。intlongdouble

顺便说一句,他们对java.util.function包中的预定义功能接口做了同样的事情,所以你有,,,和。PredicateIntPredicateDoublePredicateLongPredicate

在这里也看到一个奇妙的解释:https://stackoverflow.com/a/22919112/2886891


答案 2

推荐