使用Collectors.groupingBy按部门分组并取每组最高薪资员工,需嵌套Collectors.maxBy配合Comparator.comparingDouble;返回Map,可进一步用collectingAndThen解包为Map;若需保留所有最高薪资记录,则改用toList后过滤。

用 Collectors.groupingBy 按部门分组并取每组最高薪资记录,关键在于嵌套使用 Collectors.maxBy,配合 Comparator.comparing 比较薪资字段。
基础写法:groupingBy + maxBy
假设员工类为 Employee,含字段 String department 和 double salary:
Map<string optional>> maxSalaryByDept = employees.stream()
.collect(Collectors.groupingBy(
Employee::getDepartment,
Collectors.maxBy(Comparator.comparingDouble(Employee::getSalary))
));</string>
注意返回值是 Map,因为每组可能为空(如空集合),需用 .orElse(null) 或 .orElseThrow() 解包。
获取非 Optional 的结果(推荐)
若确保每组至少有一条数据,或希望默认返回 null,可进一步映射:
- 用
Collectors.collectingAndThen自动解包:
Map<string employee> maxSalaryByDept = employees.stream()
.collect(Collectors.groupingBy(
Employee::getDepartment,
Collectors.collectingAndThen(
Collectors.maxBy(Comparator.comparingDouble(Employee::getSalary)),
optional -> optional.orElse(null)
)
));</string>
- 若想跳过空组,可加过滤(Java 9+)或后续
.values().removeIf(Optional::isEmpty)。
处理薪资相同时保留多条记录
maxBy 只返回一条。若需所有最高薪资员工(如多个同为 25K),改用 Collectors.filtering + Collectors.toList:
Map<string list>> allMaxByDept = employees.stream()
.collect(Collectors.groupingBy(
Employee::getDepartment,
Collectors.collectingAndThen(
Collectors.toList(),
list -> {
if (list.isEmpty()) return List.of();
double maxSal = list.stream().mapToDouble(Employee::getSalary).max().orElse(0);
return list.stream()
.filter(e -> Double.compare(e.getSalary(), maxSal) == 0)
.toList();
}
)
));</string>
补充说明
若 salary 是 Integer 或 Long,用 comparingInt / comparingLong 更高效;若字段可能为 null,需用 Comparator.nullsLast(Comparator.comparingDouble(...)) 避免异常。










