Java 8 lambda用于为每个部门选择最高薪资员工

Yur*_*riy 7 java lambda java-8

class Employee {
    public string department;
    public int salary;
}

List<Employee> allEmployees = ...
Run Code Online (Sandbox Code Playgroud)

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

Tun*_*aki 11

您可以使用分组收集器执行此操作:

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

用静态导入

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;
Run Code Online (Sandbox Code Playgroud)

此代码创建了Stream所有员工,并在他们的部门的帮助下将他们分组Collectors.groupingBy.对于归类为相同密钥的所有值,我们只需要保留具有最大工资的员工,因此我们收集它们Collectors.maxBy并且比较器将工资与工资进行比较Comparator.comparingInt.因为maxBy返回一个Optional<Employee>(为了处理列表为空的情况),我们Collectors.collectingAndThen用一个只返回雇员的终结器来包装它:我们知道在这种情况下,可选项不会为空.


Tag*_*eev 5

替代解决方案:

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

当我们遇到部门的第一位员工时,我们在中添加了一个新条目Map。当找到另一名雇员时,保留较高的工资。这样,您就无需插入可选项。