通过添加类的两个BigDecimal类型属性进行分组

时间:2019-01-08 18:38:03

标签: java java-8 java-stream

我想要同一类的两个BigDecimal类型属性的总和,并将它们与该类的其他一些属性分组。

我尝试使用Collectors.groupingBy()和Collectors.reducing()方法,但这仅适用于可以汇总的一个属性。

Employee类具有以下属性:

class Employee{
 private String name;
 private BigDecimal salary;
 private BigDecimal bonus;
 private String department;

 // Getters and Setters
 }

employeeList.stream().collect(Collectors.groupingBy(
                              Employee::getDepartment, Collectors.reducing(
                                        BigDecimal.ZERO, 
                    (id, emp) -> id.add(emp.getSalary().add(emp.getBonus)), 
                                         BigDecimal::add)));

根据代码的最后一部分,Collectors.reducing(),我希望将薪金和奖金的总和与各个部门一起分组。例如,

部门A-

员工1-工资1000,奖金100

员工2-工资2000,奖金100

部门B-

员工3-工资5000,奖金100

现在我想要一张像下面的地图:

[A部门,3200],[B部门,5100]

2 个答案:

答案 0 :(得分:5)

为达到该效果,您需要结合两个单独的Collectors:groupingBy()和reduce():

Map<String, BigDecimal> result = employeeList.stream()
      .collect(Collectors
        .groupingBy(Employee::getDepartment, Collectors
          .reducing(BigDecimal.ZERO, e -> e.getBonus().add(e.getSalary()), BigDecimal::add)));

输出:     {DepartmentB=5100, DepartmentA=3200}

答案 1 :(得分:4)

首先定义这样的方法:

 public BigDecimal getSumOfBonusAndSarary(){
    return this.bonus.add(this.salary);
}

然后使用

employees.stream().collect(Collectors.groupingBy(
            Employee::getDepartment, Collectors.reducing(
                    BigDecimal.ZERO,
                    Employee::getSumOfBonusAndSarary,
                    BigDecimal::add)));

甚至使用toMap()

 employees.stream()
            .collect(Collectors.toMap(Employee::getDepartment,
                                      Employee::getSumOfBonusAndSarary,BigDecimal::add))