【问题标题】:Grouping by adding two BigDecimal type attributes of a class通过添加一个类的两个 BigDecimal 类型属性进行分组
【发布时间】:2019-01-08 18:38:03
【问题描述】:

我想要同一类的两个 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]

【问题讨论】:

  • 试试这个employees.stream().collect(Collectors.groupingBy( Employee::getDepartment, Collectors.reducing( BigDecimal.ZERO, Employee::getSum, BigDecimal::add))); 并定义一个方法如BigDecimal getSum(){ return this.bonus.add(this.salary); }

标签: java java-8 java-stream


【解决方案1】:

为了达到那个效果,你需要结合两个独立的Collectors:groupingBy()和reducing():

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}

【讨论】:

  • 换句话说,OP 对 mapperreducing 使用了类似 BiFunction 的函数,而它应该是 Functione -&gt; .... 而不是 (e, a) -&gt; ...你的回答说明了。
【解决方案2】:

首先定义一个这样的方法:

 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))

【讨论】:

  • 我喜欢使用Collectors.toMap :)
  • 其实我不想换班。我使用下面的代码它现在的工作:
  • Map depatMaps = employeeList.stream().collect(Collectors.groupingBy(em -> em.getDepartment(), Collectors.reducing(BigDecimal.ZERO, emp -> emp. getBonus().add(emp.getSalary()), BigDecimal::add)));
  • toMap() 方法看起来也不错,我在下面使用而不更改类及其工作正常:employeeList.stream().collect(Collectors .toMap(emp -> emp.getDepartment(), em -> em.getBonus().add(em.getSalary()), BigDecimal::add));
  • 我添加该方法只是为了简化。
猜你喜欢
  • 2022-06-13
  • 1970-01-01
  • 1970-01-01
  • 2022-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-09
  • 1970-01-01
相关资源
最近更新 更多