基于本文回答

播面 播面

文图音视,全方位拆解八股文
0
评论

如何将一个普通的对象流(如 Stream<T>)转换为数值流,又如何将数值流转换回普通对象流?

知识点图片

在 Java 8 及更高版本中,Stream API 提供了极其便利的方法来在普通对象流(Stream<T>数值流(IntStreamLongStreamDoubleStream之间进行相互转换。

这种转换非常重要,因为数值流(如 IntStream)避免了频繁拆装箱的性能开销,并且提供了诸如 sum()average()max() 等便利的数值聚合方法。

以下是具体的转换方法和示例:


一、普通对象流 \rightarrow 数值流 (Object Stream to Numerical Stream)

要将 Stream<T> 转换为数值流,可以使用 Stream 接口提供的 mapToInt()mapToLong()mapToDouble() 方法。这些方法需要传入一个提取数值的函数(Mapper)。

1. 转换方法:

  • mapToInt(T -> int) \rightarrow 得到 IntStream
  • mapToLong(T -> long) \rightarrow 得到 LongStream
  • mapToDouble(T -> double) \rightarrow 得到 DoubleStream

2. 代码示例:

假设有一个 User 类,包含 age(int)和 salary(double)属性:

java
class User {
    private String name;
    private int age;
    private double salary;

    // 构造函数、Getter 省略
    public User(String name, int age, double salary) {
        this.name = name;
        this.age = age;
        this.salary = salary;
    }
    public int getAge() { return age; }
    public double getSalary() { return salary; }
}

转换代码:

java
List<User> users = Arrays.asList(
    new User("张三", 20, 5000.0),
    new User("李四", 25, 8000.0),
    new User("王五", 30, 12000.0)
);

// 1. 转换为 IntStream (获取年龄)
IntStream ageStream = users.stream().mapToInt(User::getAge);

// 2. 转换为 DoubleStream (获取薪水)
DoubleStream salaryStream = users.stream().mapToDouble(User::getSalary);

// 3. 转换为 LongStream (假设将年龄转为 long)
LongStream longAgeStream = users.stream().mapToLong(User::getAge);

二、数值流 \rightarrow 普通对象流 (Numerical Stream to Object Stream)

将数值流转回对象流有两种常见场景:

  1. 转为包装类对象流(如 IntStream \rightarrow Stream<Integer>),使用 boxed()
  2. 转为自定义对象流(如 IntStream \rightarrow Stream<User>),使用 mapToObj()

1. 场景 A:转换为包装类流(装箱)

使用 boxed() 方法。这是最简单直接的转换。

  • IntStream \rightarrow Stream<Integer>
  • LongStream \rightarrow Stream<Long>
  • DoubleStream \rightarrow Stream<Double>
java
IntStream intStream = IntStream.of(1, 2, 3, 4, 5);

// 使用 boxed() 转为 Stream<Integer>
Stream<Integer> integerStream = intStream.boxed();

2. 场景 B:转换为任意自定义对象流

使用 mapToObj(IntFunction<U> mapper) 方法,可以将数值流中的每一个数字映射为一个新的对象。

java
IntStream idStream = IntStream.of(1, 2, 3);

// 将每一个 id (int) 转换为一个 User 对象,得到 Stream<User>
Stream<User> userStream = idStream.mapToObj(id -> new User("用户_" + id, 20 + id, 5000.0));

三、完整对比与总结

转换方向 源类型 目标类型 使用的方法 核心代码示例
对象 \rightarrow 数值 Stream<T> IntStream mapToInt stream.mapToInt(User::getAge)
Stream<T> LongStream mapToLong stream.mapToLong(User::getId)
Stream<T> DoubleStream mapToDouble stream.mapToDouble(User::getSalary)
数值 \rightarrow 包装类 IntStream Stream<Integer> boxed intStream.boxed()
数值 \rightarrow 自定义 IntStream Stream<T> mapToObj intStream.mapToObj(i -> new User(i))

通过合理地在对象流和数值流之间切换,你既可以享受数值流带来的高效计算性能(如 intStream.sum()),又可以方便地将其还原为业务对象进行后续处理。

00:00
00:00