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

单次遍历学生列表实现按班级统计数学与英语总分

单次遍历完成班级数学&英语总分统计

当然可以只遍历一次学生列表就完成两门学科的总分统计,核心是让每个班级对应的统计结果同时包含数学和英语的总分,遍历学生时同步更新这两个数值。下面提供几种实现方式:

方式一:自定义统计类(可读性最佳)

先定义一个专门存储两门学科总分的类,方便后续扩展和维护:

class SubjectTotal {
    int maths;
    int english;

    // 合并两个统计结果的方法
    public static SubjectTotal merge(SubjectTotal a, SubjectTotal b) {
        SubjectTotal result = new SubjectTotal();
        result.maths = a.maths + b.maths;
        result.english = a.english + b.english;
        return result;
    }
}

然后通过一次Stream遍历完成分组统计:

Map<Integer, SubjectTotal> totalPerClass = reportCard.getStudents().stream()
    .collect(Collectors.groupingBy(
        Student::getStandard,
        Collectors.reducing(
            new SubjectTotal(), // 初始值:两门分数都是0
            student -> {
                SubjectTotal st = new SubjectTotal();
                st.maths = student.getMarks().getMaths();
                st.english = student.getMarks().getEnglish();
                return st;
            },
            SubjectTotal::merge // 合并同一班级的统计结果
        )
    ));

方式二:使用现成的Entry类(无需额外定义类)

如果不想自定义类,可以用JDK自带的AbstractMap.SimpleEntry来存储两门学科的分数(key存数学,value存英语):

import java.util.AbstractMap;

Map<Integer, AbstractMap.SimpleEntry<Integer, Integer>> totalPerClass = reportCard.getStudents().stream()
    .collect(Collectors.groupingBy(
        Student::getStandard,
        Collectors.reducing(
            new AbstractMap.SimpleEntry<>(0, 0),
            student -> new AbstractMap.SimpleEntry<>(
                student.getMarks().getMaths(),
                student.getMarks().getEnglish()
            ),
            (entry1, entry2) -> new AbstractMap.SimpleEntry<>(
                entry1.getKey() + entry2.getKey(), // 累加数学分数
                entry1.getValue() + entry2.getValue() // 累加英语分数
            )
        )
    ));

方式三:使用toMap实现

也可以通过Collectors.toMap来完成,逻辑和上面一致:

Map<Integer, SubjectTotal> totalPerClass = reportCard.getStudents().stream()
    .collect(Collectors.toMap(
        Student::getStandard, // 分组键:班级
        student -> {
            SubjectTotal st = new SubjectTotal();
            st.maths = student.getMarks().getMaths();
            st.english = student.getMarks().getEnglish();
            return st;
        },
        SubjectTotal::merge // 重复班级时合并统计结果
    ));

以上三种方式都只需要遍历一次学生列表,就能同时完成两门学科的班级总分统计,相比原来两次遍历的写法更高效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 10:03:19