You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Java 8 Stream获取各部门薪资第二高的员工

按部门获取薪资第二高的员工实现方案

核心思路

先按部门对员工分组,再对每个部门的员工集合按薪资降序排序,跳过薪资最高的第一个员工后,取第一个结果就是该部门薪资第二高的员工。同时要处理部门员工数不足2人的边界情况,避免空指针异常。

实现代码(保留同薪资员工的场景)

如果需要保留同薪资的员工(即部门内有多个最高薪员工时,第二高可以是同薪资的另一位员工),可以用以下代码:

import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

public class EmployeeDemo {
    public static void main(String[] args) {
        List<Employee> employeeList = List.of(
                new Employee(10000L, "技术部"),
                new Employee(20000L, "技术部"),
                new Employee(20000L, "技术部"),
                new Employee(15000L, "技术部"),
                new Employee(25000L, "市场部"),
                new Employee(22000L, "市场部"),
                new Employee(30000L, "人事部")
        );

        Map<String, Optional<Employee>> secondHighestByDept = employeeList.stream()
                .collect(Collectors.groupingBy(
                        Employee::getDepartment,
                        Collectors.collectingAndThen(
                                Collectors.toList(),
                                empList -> empList.stream()
                                        .sorted(Comparator.comparingLong(Employee::getSalary).reversed())
                                        .skip(1)
                                        .findFirst()
                        )
                ));

        // 输出结果
        secondHighestByDept.forEach((dept, empOpt) -> {
            System.out.printf("部门:%s - ", dept);
            empOpt.ifPresentOrElse(
                    emp -> System.out.printf("薪资第二高的员工薪资:%d%n", emp.getSalary()),
                    () -> System.out.println("无薪资第二高的员工")
            );
        });
    }
}

class Employee {
    private Long salary;
    private String department;

    public Employee(Long salary, String department) {
        this.salary = salary;
        this.department = department;
    }

    public Long getSalary() {
        return salary;
    }

    public String getDepartment() {
        return department;
    }
}

实现代码(严格取薪资第二高的场景)

如果需要严格获取薪资低于最高薪的员工(即排除同薪资的最高薪员工),可以用TreeSet自动排序并去重薪资:

import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.TreeSet;
import java.util.stream.Collectors;

public class EmployeeDemo {
    public static void main(String[] args) {
        List<Employee> employeeList = List.of(
                new Employee(10000L, "技术部"),
                new Employee(20000L, "技术部"),
                new Employee(20000L, "技术部"),
                new Employee(15000L, "技术部"),
                new Employee(25000L, "市场部"),
                new Employee(22000L, "市场部"),
                new Employee(30000L, "人事部")
        );

        Map<String, Optional<Employee>> secondHighestByDept = employeeList.stream()
                .collect(Collectors.groupingBy(
                        Employee::getDepartment,
                        Collectors.collectingAndThen(
                                // 用TreeSet按薪资降序排序,自动去重同薪资的员工
                                Collectors.toCollection(() -> new TreeSet<>(Comparator.comparingLong(Employee::getSalary).reversed())),
                                sortedSet -> {
                                    var iterator = sortedSet.iterator();
                                    if (iterator.hasNext()) iterator.next(); // 跳过最高薪员工
                                    return iterator.hasNext() ? Optional.of(iterator.next()) : Optional.empty();
                                }
                        )
                ));

        // 输出结果
        secondHighestByDept.forEach((dept, empOpt) -> {
            System.out.printf("部门:%s - ", dept);
            empOpt.ifPresentOrElse(
                    emp -> System.out.printf("薪资第二高的员工薪资:%d%n", emp.getSalary()),
                    () -> System.out.println("无薪资第二高的员工")
            );
        });
    }
}

class Employee {
    private Long salary;
    private String department;

    public Employee(Long salary, String department) {
        this.salary = salary;
        this.department = department;
    }

    public Long getSalary() {
        return salary;
    }

    public String getDepartment() {
        return department;
    }
}

关键说明

  • 两种实现都用Optional包装结果,避免部门只有1名员工时出现空指针。
  • 第一种方案适合需要保留同薪资员工的场景,第二种方案适合需要严格区分薪资层级的场景。

内容的提问来源于stack exchange,提问作者JNRaj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 07:40:33