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

如何在Java中按科目优先级及分数对学生列表排序并排名?

学生按科目优先级排序并计算排名解决方案

问题需求

  • 根据给定的subjectPriorityOrder(如[MATHS, ENGLISH, SCIENCE, COMPUTER])对学生进行排名
  • 排序规则:按科目优先级依次比较分数,优先级高的科目分数高的学生排前;若前一科目分数相同,则比较下一优先级科目;若学生无对应科目分数,视为0分处理
  • 完成排序后为学生设置排名(同分学生共享同一排名)

现有类结构

Student.java

private Long id;
private String firstName;
private String lastName;
private List<Subject> subjects;
// 需添加rank字段及getter/setter
// private Integer rank;

Subject.java

private String name;
private Integer marks;
// 省略getter/setter

输入示例

[
{"id": 1,"firstName": "Alice", "lastName": "Alice",
        "subjects": [
            {"name": "SCIENCE", "marks": 50},
            {"name": "MATHS", "marks": 45}]},
{"id": 2,"firstName": "Bob", "lastName": "Bob",
        "subjects": [
            {"name": "MATHS", "marks": 80},
            {"name": "ENGLISH", "marks": 85}
        ]},
{"id": 3, "firstName": "John","lastName": "John",
        "subjects": [
            {"name": "MATHS", "marks": 80},
            {"name": "SCIENCE", "marks": 45},
            {"name": "ENGLISH", "marks": 75}
        ]},
{"id": 4,"firstName": "Thomas","lastName": "Thomas",
        "subjects": [
            {"name": "MATHS", "marks": 90}
        ]}
]

现有代码问题

原代码仅按科目是否存在筛选排序,未实现同科目分数高低比较,也未处理多科目优先级递进比较逻辑,排名设置逻辑完全缺失。

解决方案

1. 编写科目优先级比较的Comparator

核心实现多科目递进比较的排序逻辑:

private Comparator<Student> getStudentComparator(List<String> subjectPriorityOrder) {
    return (s1, s2) -> {
        // 按科目优先级逐科比较分数
        for (String subjectName : subjectPriorityOrder) {
            Integer marks1 = getSubjectMarks(s1, subjectName);
            Integer marks2 = getSubjectMarks(s2, subjectName);
            // 分数降序排列,高分在前
            int compareResult = marks2.compareTo(marks1);
            if (compareResult != 0) {
                return compareResult;
            }
            // 分数相同则继续比较下一科目
        }
        // 所有科目分数一致时,按ID升序保证排序稳定性
        return s1.getId().compareTo(s2.getId());
    };
}

// 获取学生指定科目的分数,无对应科目则返回0
private Integer getSubjectMarks(Student student, String subjectName) {
    return student.getSubjects().stream()
            .filter(subject -> subject.getName().equals(subjectName))
            .findFirst()
            .map(Subject::getMarks)
            .orElse(0);
}

2. 实现排序与排名逻辑

替换原有sortStudentList方法,完成排序+排名计算:

public List<Student> sortStudentList(List<Student> studentList, List<String> subjectPriorityOrder) {
    if (studentList == null || studentList.isEmpty() || subjectPriorityOrder == null || subjectPriorityOrder.isEmpty()) {
        return studentList;
    }

    // 复制原列表避免修改输入数据
    List<Student> sortedStudents = new ArrayList<>(studentList);
    // 使用自定义Comparator排序
    sortedStudents.sort(getStudentComparator(subjectPriorityOrder));

    // 计算排名(处理同分同名次)
    if (!sortedStudents.isEmpty()) {
        int currentRank = 1;
        sortedStudents.get(0).setRank(currentRank);
        for (int i = 1; i < sortedStudents.size(); i++) {
            Student current = sortedStudents.get(i);
            Student previous = sortedStudents.get(i - 1);
            boolean isSameRank = true;
            // 校验所有优先级科目分数是否完全一致
            for (String subjectName : subjectPriorityOrder) {
                Integer currentMarks = getSubjectMarks(current, subjectName);
                Integer prevMarks = getSubjectMarks(previous, subjectName);
                if (!currentMarks.equals(prevMarks)) {
                    isSameRank = false;
                    break;
                }
            }
            if (isSameRank) {
                current.setRank(previous.getRank());
            } else {
                currentRank = i + 1;
                current.setRank(currentRank);
            }
        }
    }

    return sortedStudents;
}

3. 补充Student类的rank字段

给Student类添加排名属性及访问方法:

private Integer rank;

public Integer getRank() {
    return rank;
}

public void setRank(Integer rank) {
    this.rank = rank;
}

测试结果

针对输入示例,排序后学生顺序及排名为:

  1. Thomas(MATHS 90)→ 排名1
  2. Bob(MATHS 80,ENGLISH 85)→ 排名2
  3. John(MATHS 80,ENGLISH 75)→ 排名3
  4. Alice(MATHS 45)→ 排名4

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 21:55:00