首页 > 编程笔记 > Java笔记 阅读:24

Java Stream.map()方法:实现数据映射(附带实例)

数据的映射和过滤概念不同,过滤是在流中找到符合条件的元素,映射是在流中获得具体的数据。

Java 的 Stream 接口提供了 map() 方法用来实现数据映射,map() 方法会按照参数中的函数逻辑获取新的流对象,新的流对象中元素类型可能与旧流对象元素类型不相同。

【实例 1】获取开发部所有员工的名单。
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.ArrayList;

public class Employee {
    private String name;      // 姓名
    private int age;          // 年龄
    private double salary;    // 工资
    private String sex;       // 性别
    private String dept;      // 部门

    // 构造方法
    public Employee(String name, int age, double salary, String sex, String dept) {
        this.name = name;
        this.age = age;
        this.salary = salary;
        this.sex = sex;
        this.dept = dept;
    }

    // 重写 toString()方法,方便输出员工信息
    public String toString() {
        return "name=" + name + ", age=" + age + ", salary=" + salary + ", sex=" + sex + ", dept=" + dept;
    }

    // 以下是员工属性的 getter 方法
    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public double getSalary() {
        return salary;
    }

    public String getSex() {
        return sex;
    }

    public String getDept() {
        return dept;
    }

    static List<Employee> getEmpList() { // 提供数据初始化方法
        List<Employee> list = new ArrayList<Employee>();
        list.add(new Employee("老张", 40, 9000, "男", "运营部"));
        list.add(new Employee("小刘", 24, 5000, "女", "开发部"));
        list.add(new Employee("大刚", 32, 7500, "男", "销售部"));
        list.add(new Employee("翠花", 28, 5500, "女", "销售部"));
        list.add(new Employee("小马", 21, 3000, "男", "开发部"));
        list.add(new Employee("老王", 35, 6000, "女", "人事部"));
        list.add(new Employee("小王", 21, 3000, "女", "人事部"));
        return list;
    }
}

public class MapDemo {
    public static void main(String[] args) {
        List<Employee> list = Employee.getEmpList(); // 获取公共类的测试数据
        Stream<Employee> stream = list.stream(); // 获取集合流对象
        // 将所有开发部的员工过滤出来
        stream = stream.filter(people -> "开发部".equals(people.getDept()));
        // 将所有员工的名字映射成一个新的流对象
        Stream<String> names = stream.map(Employee::getName);
        // 将流对象重新封装成一个 List 集合
        List<String> result = names.collect(Collectors.toList());
        // 遍历结果集
        for (String emp : result) {
            System.out.println(emp); // 输出所有姓名
        }
    }
}
程序中定义了 Employee 类,在获取员工集合后,先过滤出开发部的员工,再引用员工类的 getName() 方法作为 map() 方法的映射参数,这样就获取到开发部员工名单。

运行结果如下:

小刘
小马

结果输出了开发部两位员工的名字,但没有输出这两位员工的其他信息,这个就是映射的结果。

除了可以映射出员工名单,还可以对映射数据进行加工处理。例如,统计销售部一个月的薪资总额。因为涉及数字计算,所以需要让 Stream 对象转为可以进行数学运算的数字流。因为薪资类型是 double 类型,所以应该调用 mapToDouble() 方法进行转换。

【实例 2】计算销售部一个月的薪资总额。本例使用了例 1 定义的 Employee 类,在获取员工集合后,先过滤出销售部的员工,再引用员工类的 getSalary() 方法作为 mapToDouble() 的映射参数,获取到 DoubleStream 对象后,调用该对象的 sum() 方法,就可以计算出销售部的薪资总和。具体代码如下:
import java.util.List;
import java.util.stream.DoubleStream;
import java.util.stream.Stream;

public class MapToInDemo {
    public static void main(String[] args) {
        List<Employee> list = Employee.getEmpList(); // 获取公共类的测试数据
        Stream<Employee> stream = list.stream(); // 获取集合流对象
        // 将所有销售部的员工过滤出来
        stream = stream.filter(people -> "销售部".equals(people.getDept()));
        // 将所有员工的薪资映射成一个新的流对象
        DoubleStream salaries = stream.mapToDouble(Employee::getSalary);
        double sum = salaries.sum(); // 统计流中元素的和
        System.out.println("销售部一个月的薪资总额:" + sum);
    }
}
运行结果如下:

销售部一个月的薪资总额:13000.0

除 DoubleStream 类外,java.util.stream 包还提供了 IntStream 类和 LongStream 类以应对不同的计算场景。

相关文章