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

如何按属性分组并获取最大值映射?Java Stream优化实现

按学生分组获取最高成绩的Stream优化实现

场景说明

现有StudentGrade类定义如下:

public class StudentGrade {
   int studentId;
   double value;
   Date date;
   // 省略getter、setter等方法
}

需求是将List<StudentGrade>按studentId分组,得到以studentId为键、对应学生最高成绩的StudentGrade对象为值的Map<Integer, StudentGrade>。原实现需要额外初始化HashMap并处理Optional,以下是无需额外容器、全程用Stream完成的优化方案。


优化方案1:用collectingAndThen包装maxBy

通过collectingAndThen直接将maxBy返回的Optional<StudentGrade>提取为实际值,一步生成目标Map:

public Map<Integer, StudentGrade> getMaxGradeByStudent(List<StudentGrade> grades) {
    return grades.stream().collect(
        Collectors.groupingBy(
            StudentGrade::getStudentId,
            Collectors.collectingAndThen(
                Collectors.maxBy(Comparator.comparing(StudentGrade::getValue)),
                Optional::get
            )
        )
    );
}

注意:若某studentId对应分组为空(原列表无该学生数据),Optional::get会抛出NoSuchElementException,可根据业务需求改用Optional.orElse(null)或指定默认值。


优化方案2:直接使用Collectors.toMap

利用toMap的合并函数,遇到相同studentId的元素时保留成绩更高的对象,逻辑更简洁且无需处理Optional:

public Map<Integer, StudentGrade> getMaxGradeByStudent(List<StudentGrade> grades) {
    return grades.stream().collect(
        Collectors.toMap(
            StudentGrade::getStudentId,
            grade -> grade,
            (existing, newGrade) -> existing.getValue() >= newGrade.getValue() ? existing : newGrade
        )
    );
}

如果存在多个成绩相同的最高记录,此方案会保留先出现的对象;若需按其他维度(如最新date)筛选,可在合并函数中扩展判断逻辑。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 09:05:23