Java list 根据条件多个字段分组求和

在Java中,我们经常会遇到需要对一个列表进行分组求和的需求。例如,我们有一个员工列表,其中包含每个员工的姓名、部门和薪水信息。我们想要按部门对员工进行分组,并计算每个部门的总薪水。本文将介绍如何使用Java的列表和流操作来实现这个功能。

准备工作

首先,我们需要创建一个Employee类来表示员工信息。该类包含三个属性:姓名、部门和薪水。

public class Employee {
    private String name;
    private String department;
    private double salary;

    public Employee(String name, String department, double salary) {
        this.name = name;
        this.department = department;
        this.salary = salary;
    }

    // 省略 getter 和 setter 方法
}

接下来,我们创建一个员工列表,并添加一些示例数据。

List<Employee> employees = new ArrayList<>();
employees.add(new Employee("Alice", "HR", 5000));
employees.add(new Employee("Bob", "IT", 6000));
employees.add(new Employee("Charlie", "HR", 5500));
employees.add(new Employee("David", "IT", 7000));
employees.add(new Employee("Eve", "HR", 4500));

分组求和

我们可以使用Java 8引入的流操作来对员工列表进行分组求和。首先,我们需要使用Collectors.groupingBy方法按部门对员工进行分组。然后,我们利用Collectors.summingDouble方法对每个组的薪水进行求和。

Map<String, Double> departmentSalaries = employees.stream()
    .collect(Collectors.groupingBy(Employee::getDepartment,
             Collectors.summingDouble(Employee::getSalary)));

上述代码中,Collectors.groupingBy方法的第一个参数是一个函数,用于指定分组的条件,这里我们使用Employee::getDepartment方法来获取员工的部门。Collectors.summingDouble方法的参数也是一个函数,用于指定求和的字段,这里我们使用Employee::getSalary方法来获取员工的薪水。

结果展示

我们可以通过遍历departmentSalaries来展示每个部门的总薪水。

for (Map.Entry<String, Double> entry : departmentSalaries.entrySet()) {
    String department = entry.getKey();
    double totalSalary = entry.getValue();
    System.out.println("Department: " + department + ", Total Salary: " + totalSalary);
}

运行以上代码,输出结果如下:

Department: HR, Total Salary: 15000.0
Department: IT, Total Salary: 13000.0

序列图

下面是一个简单的序列图,展示了以上代码的执行过程。

sequenceDiagram
    participant Employees
    participant Stream
    participant Collectors
    participant departmentSalaries

    Employees->>Stream: 创建员工列表
    Stream->>Collectors: 分组求和
    Collectors->>departmentSalaries: 返回结果
    departmentSalaries->>Employees: 显示结果

总结

本文介绍了如何使用Java的列表和流操作来对多个字段进行分组求和。通过使用Collectors.groupingByCollectors.summingDouble方法,我们可以很方便地实现这个功能。希望本文对你有所帮助。