I need to find the Students ranks based on the subjectPriorityOrder given. Student list contains subject list with marks. Subject Priority Order list has the priority order which one we should have to give a first priority, 2nd, 3rd and so on [MATHS, ENGLISH, SCIENCE, COMPUTER]
Student.java
private Long id;
private String firstName;
private String lastName;
private List<Subject> subjects;
Subject.java
private String name;
private Integer marks;
Input - Student List
[
{"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}
]}
]
Expected Output Details:
If any of the student has highest marks in Maths, we need to put 1st rank to that student.
If two students (StudentA & StudentB ) have same marks in Maths and StudentB has highest marks in English, we need to put 1st Rank to StudentB and 2nd Rank to StudentA
Tried scenario:
I have written the code to sort the student list based on the priority order given.
But I don't know how to compare the marks for each subject with respect to the studentList (one student with other student).
How should I write the Comparator for each Subjects and sort the student list by comparing one student subject wise marks with other student's subject wise marks.
Kindly help me to complete this sorting.
The below code sorting the student list by subjectPriorityOrder and it is not comparing the marks.
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;
}
This is the sample code I have written. There are many improvements that can be made, such as having Subject as an Enum, and then having subjects as a Map of <Subject, Integer>.
As for the comparator I have written, you can see that it defines an internal subject priority, and based on the priority it gets a students grades. Based on your comment, I have written a method getSubjectGrade(String subject) that gets a grade of a subject if it exist, defaulting to zero if not.
I then return the comparison if the two students do not have the same grades, else I continue to compare the students grades. There is room for further improvement, such as having the comparator have a dynamic internal subject priority but I wont go further.
Output: