【问题标题】:Java 8 lambda for selecting top salary employee for each departmentJava 8 lambda 用于为每个部门选择最高薪员工
【发布时间】:2016-07-02 15:27:07
【问题描述】:
class Employee {
    public string department;
    public int salary;
}

List<Employee> allEmployees = ...

我需要一个列表,每个部门只有 1 名最高薪员工。 allEmployees 是源列表。

【问题讨论】:

    标签: java lambda java-8


    【解决方案1】:

    您可以使用分组收集器来做到这一点:

    Map<String, Employee> topEmployees =
        allEmployees.stream()
                    .collect(groupingBy(
                        e -> e.department,
                        collectingAndThen(maxBy(comparingInt(e -> e.salary)), Optional::get) 
                    ));
    

    静态导入

    import static java.util.Comparator.comparingInt;
    import static java.util.stream.Collectors.collectingAndThen;
    import static java.util.stream.Collectors.groupingBy;
    import static java.util.stream.Collectors.maxBy;
    

    此代码创建一个包含所有员工的Stream,并在Collectors.groupingBy 的帮助下将他们与所在部门分组。对于归类到同一键的所有值,我们只需要保留最高薪水的员工,因此我们用Collectors.maxBy 收集它们,比较器将薪水与Comparator.comparingInt 进行比较。由于maxBy 返回一个Optional&lt;Employee&gt;(以处理列表为空的情况),我们通过调用Collectors.collectingAndThen 来包装它,并使用一个只返回员工的finisher:我们知道在这种情况下可选的赢了不要为空。

    【讨论】:

      【解决方案2】:

      替代解决方案:

      Map<String, Employee> topEmployees =
          allEmployees.stream()
                  .collect(Collectors.toMap(
                      e -> e.department,
                      e -> e,
                      BinaryOperator.maxBy(Comparator.comparingInt(e -> e.salary)) 
                  ));
      

      当我们遇到该部门的第一个员工时,我们向Map 添加一个新条目。当找到另一名员工时,将保留一名薪水较高的员工。这样你就不需要干预可选了。

      【讨论】:

        【解决方案3】:

        /假设您有一个员工列表作为 List employeeList; 要首先找到部门工资,您需要有员工比较器/

        Comparator<Employee> bySalary = Comparator.comparing(Employee::getSalary);
        

        然后找到部门明智的最高薪水

        Map<String, Optional<Employee>> collect = 
                employeeList.stream().collect(
                    Collectors.groupingBy(
                        Employee::getDept,
                        Collectors.reducing(BinaryOperator.maxBy(bySalary))
            )
        );
        

        我们在这里做的是, 我们根据那里的部门对员工进行分组。 除了分组,我们说还给我那个部门的最高薪水者, 最后只选择最多一个。 在 Employee 类中查看输出覆盖 toString 方法并执行 */

        collect.entrySet().stream().forEach(System.out::println);
        

        【讨论】:

          【解决方案4】:

          老实说,这不是一个解决方案。 由于声誉低下,我无法发表评论,这只是一个很小的观察,导致了这种更正/即兴创作。

          我遇到了同样的情况,我尝试了上述对我有用的 Tagir Valeev's 解决方案。 我在我的IDE中使用它,但是返回的结果是错误的,因为编译器抱怨如下:

          编译时错误:无法从Map&lt;Object, Object&gt; 转换为Map&lt;String, Employee&gt;。

          这就是我理解这里的预期返回类型是 Object 类型而不是我们期望的类型,即 Map&lt;String, Employee&gt;

          我只需要将结果接收到Map&lt;Object, Object&gt; 而不是Map&lt;String, Employee&gt;。

          因此,下面的代码迭代了Map&lt;Object, Object&gt; topEmployees,并将最终的预期结果存储到Map&lt;String, Employee&gt; finalResult;

          Tagir Valeev 的解决方案如下,我在接收端进行了调整:

          Map<Object, Object> topEmployees = empList.stream()
                      .collect(Collectors.groupingBy(e -> e.department, 
                              Collectors.collectingAndThen(
                                      Collectors.maxBy(Comparator.comparingDouble(e -> e.salary)), Optional::get
                                                          )
                                          )
                      );
          

          我写的额外代码如下:

          for(Map.Entry<Object, Object> token : topEmployees.entrySet()) {
                  finalResult.put((String) token.getKey() , (Employee) token.getValue());
              }
          

          希望这对某人有所帮助。谢谢。

          【讨论】:

            【解决方案5】:

            Map 结果 = li.stream().collect(Collectors.groupingBy(Emp::getDept, Collectors.reducing(BinaryOperator.maxBy(Comparator.comparing(Emp::getSalary))) ));

            【讨论】:

            • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-11-20
            • 2013-09-21
            • 1970-01-01
            • 1970-01-01
            • 2021-01-03
            • 1970-01-01
            相关资源
            最近更新 更多