Search code examples
javalambdajava-8

Java 8 lambda for selecting top salary employee for each department


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

List<Employee> allEmployees = ...

I need to have a list that will have only 1 top salary employee for each department. allEmployees is the source list.


Solution

  • You can do that with a grouping collector:

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

    with the static imports

    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;
    

    This code creates a Stream of all the employees and groups them with their department with the help of Collectors.groupingBy. For all the values classified to the same key, we need to keep only the employee with the maximum salary, so we collect them with Collectors.maxBy and the comparator compares the salary with Comparator.comparingInt. Since maxBy returns an Optional<Employee> (to handle the case where there the list is empty), we wrap it with a call to Collectors.collectingAndThen with a finisher that just returns the employee: we know in this case that the optional won't be empty.