如何使用java通过比较子列表元素来对父列表进行排序和排名? [已关闭]

问题描述 投票:0回答:1

我需要根据给出的科目优先顺序找到学生排名。学生列表包含带有分数的科目列表。科目优先顺序列表有优先顺序,我们应该给予第一优先,第二,第三等等[数学,英语,科学,计算机]

学生.java

private Long id;
private String firstName;
private String lastName;
private List<Subject> subjects;

Subject.java

private String name;
private Integer marks;

输入-学生名单

[
{"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}
        ]}
]

预期输出详细信息:

如果任何学生在数学方面得分最高,我们需要将该学生排名第一。

如果两个学生(学生A和学生B)在数学上有相同的分数,而学生B在英语上得分最高,我们需要将第一名归给学生B,将第二名归给学生A

尝试过的场景:

我已经编写了根据给定的优先级顺序对学生列表进行排序的代码。

But I don't know how to compare the marks for each subject with respect to the studentList (one student with other student).

我应该如何为每个科目编写比较器,并通过将一个学生的科目明智分数与其他学生的科目明智分数进行比较来对学生列表进行排序。

请帮我完成这次排序。

下面的代码按 subjectPriorityOrder 对学生列表进行排序,并且不比较分数。

List<String> subjectPriorityOrder = Arrays.asList("MATHS", "ENGLISH", "SCIENCE", "COMPUTER", "HISTORY");

public List<Student> sortStudentList(List<Student> studentList, List<String> subjectPriorityOrder) {
        if (studentList != null && !studentList.isEmpty() && subjectPriorityOrder != null && !subjectPriorityOrder.isEmpty()) {
            List<Student> sortedList = new ArrayList<>();
            List<Student> unSortedList = new ArrayList<>();
            unSortedList.addAll(studentList);
            Integer studentRank = 0;
            for (String subjectName : subjectPriorityOrder) {
                for (Iterator<Student> studentIterator = studentList.iterator(); studentIterator.hasNext(); ) {
                    Student student = studentIterator.next();
                    Subject subject = getSubjectIfFound(student.getBenefitValues(), subjectName); // search for the item on the list by subjectName
                    if (subject != null) {
                        LOGGER.info("####### Matched Student ID ######## {}", student.getId());
                        //student.setRank(++studentRank); TODO: Need to set a rank after comparing the marks
                        sortedList.add(student);       // if found add to sorted list
                        //unSortedList.remove(student);
                        studentIterator.remove();      // remove added item from iterator
                        studentList.remove(student);      // remove the added item from the studentList
                        LOGGER.info("-----------------------------------------------------------------");
                    }
                }
            }
            sortedList.addAll(studentList);        // append the remaining items on the unsorted list to new sorted list
            return sortedList;
        } else {
            return studentList;
        }
    }

    private Subject getSubjectIfFound(List<Subject> subjectMarks, String subjectName) {
        for (Subject subject : subjectMarks) {
// TODO: Need to compare marks as well
            if (subject.getName().equals(subjectName)) {
                return subject;
            }
        }
        return null;
    }
java sorting java-8 comparator
1个回答
0
投票

首先,我不喜欢那些没有付出足够努力的家庭作业问题,只是说帮我解决这个问题。您没有尝试找出比较器是什么,也没有尝试编写自己的比较器。

public class Subject {
    String name;
    Integer marks;

    public Subject(String name, Integer marks) {
        this.name = name;
        this.marks = marks;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getMarks() {
        return marks;
    }

    public void setMarks(Integer marks) {
        this.marks = marks;
    }

    @Override
    public String toString() {
        return "Subject{" +
                "name='" + name + '\'' +
                ", marks=" + marks +
                '}';
    }
}


import java.util.List;

public class Student {
    Long id;
    List<Subject> subjects;

    public Student(Long id, List<Subject> subjects) {
        this.id = id;
        this.subjects = subjects;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Integer getSubjectGrade(String subject) {
        for (final var sub : subjects) {
            if (sub.getName().equals(subject)) {
                return sub.getMarks();
            }
        }
        return 0;
    }

    public List<Subject> getSubjects() {
        return subjects;
    }

    public void setSubjects(List<Subject> subjects) {
        this.subjects = subjects;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", subjects=" + subjects +
                '}';
    }
}


import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        final var alice = new Student(1L, List.of(new Subject("SCIENCE", 50), new Subject("MATHS", 45)));
        final var bob = new Student(2L, List.of(new Subject("MATHS", 80), new Subject("ENGLISH", 85)));
        final var john = new Student(3L, List.of(new Subject("MATHS", 80), new Subject("SCIENCE", 45), new Subject("ENGLISH", 75)));
        final var thomas = new Student(4L, List.of(new Subject("MATHS", 90)));

        final var students = new ArrayList<>(List.of(alice, bob, john, thomas));
        System.out.println(students);
        System.out.println(students.stream().sorted(new StudentSubjectComparator()).toList());
    }
}

class StudentSubjectComparator implements Comparator<Student> {
    private static final String[] SubjectPriority = {"MATHS", "ENGLISH", "SCIENCE", "COMPUTER"};

    @Override
    public int compare(Student o1, Student o2) {
        for (final var subject : SubjectPriority) {
            int comparison = o1.getSubjectGrade(subject).compareTo(o2.getSubjectGrade(subject));
            if (comparison == 0) {
            } else {
                return -comparison; // note the negative sign. This is what sorts in reverse order (descending)
            }
        }
        return 0;
    }
}

这是我编写的示例代码。可以进行许多改进,例如将主题作为枚举,然后将主题作为 的映射。

对于我编写的比较器,您可以看到它定义了内部学科优先级,并根据优先级获得学生的成绩。根据您的评论,我编写了一个方法 getSubjectGrade(String subject) ,该方法可以获取主题的评分(如果存在),如果不存在则默认为零。

如果两个学生的成绩不同,我会返回比较结果,否则我会继续比较学生的成绩。还有进一步改进的空间,例如让比较器具有动态的内部主题优先级,但我不会进一步改进。

输出:

[Student{id=1, subjects=[Subject{name='SCIENCE', marks=50}, Subject{name='MATHS', marks=45}]}, Student{id=2, subjects=[Subject{name='MATHS', marks=80}, Subject{name='ENGLISH', marks=85}]}, Student{id=3, subjects=[Subject{name='MATHS', marks=80}, Subject{name='SCIENCE', marks=45}, Subject{name='ENGLISH', marks=75}]}, Student{id=4, subjects=[Subject{name='MATHS', marks=90}]}]
[Student{id=4, subjects=[Subject{name='MATHS', marks=90}]}, Student{id=2, subjects=[Subject{name='MATHS', marks=80}, Subject{name='ENGLISH', marks=85}]}, Student{id=3, subjects=[Subject{name='MATHS', marks=80}, Subject{name='SCIENCE', marks=45}, Subject{name='ENGLISH', marks=75}]}, Student{id=1, subjects=[Subject{name='SCIENCE', marks=50}, Subject{name='MATHS', marks=45}]}]
© www.soinside.com 2019 - 2024. All rights reserved.