Java 装箱流

Java 装箱流,用户希望利用基本类型流(primitive stream)创建集合,既可以使用 java.util.stream.IntStream 接口定义的 boxed 方法来包装元素,也可以使用合适的包装器类(wrapper class)来映射值,还可以使用 collect 方法的三参数形式。

Java 装箱流 问题描述

用户希望利用基本类型流(primitive stream)创建集合。

Java 装箱流 解决方案

既可以使用 java.util.stream.IntStream 接口定义的 boxed 方法来包装元素,也可以使用合适的包装器类(wrapper class)来映射值,还可以使用 collect 方法的三参数形式。

Java 装箱流 具体实例

在处理对象流(object stream)时,可以通过 Collectors 类提供的某种静态方法将流转换为集合。例如,对于一个给定的字符串流,例 3-8 显示了如何创建 List<String>

例 3-8 将字符串流转换为列表

List<String> strings = Stream.of("this", "is", "a", "list", "of", "strings")
    .collect(Collectors.toList());

然而,同样的过程并不适合处理基本类型流,例 3-9 中的代码无法编译。

例 3-9 将 int 流转换为 Integer 列表(无法编译)

IntStream.of(3, 1, 4, 1, 5, 9)
    .collect(Collectors.toList()); // 无法编译

有三种替代方案可以解决这个问题。第一种方案是利用 boxed 方法,将 IntStream 转换为 Stream<Integer>,如例 3-10 所示。

例 3-10 使用 boxed 方法

List<Integer> ints = IntStream.of(3, 1, 4, 1, 5, 9)
    .boxed() ➊
    .collect(Collectors.toList());

➊ 将 int 转换为 Integer
第二种方案是利用 mapToObj 方法,将基本类型流中的每个元素转换为包装类的一个实例,如例 3-11 所示。

例 3-11 使用 mapToObj 方法

List<Integer> ints = IntStream.of(3, 1, 4, 1, 5, 9)
    .mapToObj(Integer::valueOf)
    .collect(Collectors.toList())

mapToIntmapToLongmapToDouble 方法将对象流解析为相关的基本类型流,与之类似,IntStreamLongStreamDoubleStream 中的 mapToObj 方法将基本类型流转换为相关包装类的实例。在本例中,mapToObj 方法的参数为 Integer 类定义的静态方法 valueOf

出于性能方面的考虑,构造函数 Integer(int val) 已被 JDK 9 弃用,建议改用 Integer.valueOf(int)

第三种方案是采用 collect 方法的三参数形式,其签名为:

<R> R collect(Supplier<R> supplier,
              ObjIntConsumer<R> accumulator,
              BiConsumer<R,R> combiner)

collect 方法的用法如例 3-12 所示。

例 3-12 使用 collect 方法的三参数形式

List<Integer> ints = IntStream.of(3, 1, 4, 1, 5, 9)
    .collect(ArrayList<Integer>::new, ArrayList::add, ArrayList::addAll);

如例所示,SupplierArrayList<Integer> 的构造函数。累加器(accumulator)为 add 方法,表示如何为列表添加单个元素。仅在并行操作中使用的组合器(combiner)是 addAll 方法,它能将两个列表合二为一。尽管 collect 的三参数形式并不常见,但理解其用法对开发很有好处。
以上三种方案均无不妥,采用哪种方案取决于开发人员的编程风格。此外,如果希望将流转换为数组而非列表,那么采用 toArray 方法也不错,如例 3-13 所示。

例 3-13 将 IntStream 转换为 intArray

int[] intArray = IntStream.of(3, 1, 4, 1, 5, 9).toArray();

本范例讨论的三种方案都是必不可少的,这是 Java 最初将基本数据类型与对象区别对待的结果,因泛型的引入而变得复杂。不过,一旦掌握要领,使用 boxedmapToObj 方法还是很容易的。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程