В интересах упрощения (т. Е. Принципа KISS) и объяснения моей «подсказки», касающейся составного ключа, ниже приводится обработанный пример.
«Ключ» к решению состоит в том, чтобы позволить дереву сортировать данные естественным образом (не IMHO, чтобы добавить к коду, делающему его более сложным, предоставляя ручную сортировку). Таким образом, ученический класс должен вернуть ключ, который дерево может естественно отсортировать.
Чтобы получить желаемый результат сортировки, ключ для дерева (общая оценка, имя студента).
Вот пересмотренный класс Student (за исключением получателей и установщиков, но я добавил новый конструктор, чтобы облегчить мне жизнь):
public class Student {
private String name;
private Integer rollNumber;
private int m1;
private int m2;
private int m3;
private int totMarks;
//Getter setter
public Student() {
}
public Student(String name, Integer rollNumber, int m1, int m2, int m3) {
this.name = name;
this.rollNumber = rollNumber;
this.m1 = m1;
this.m2 = m2;
this.m3 = m3;
this.totMarks = m1 + m2 + m3;
}
public String getKey() {
// return String.format("%d-%s", totMarks, name); // WRONG!
return String.format("%04d-%s", totMarks, name); // Right
}
public String toString() {
return String.format("%06d: %s - %d", rollNumber, name, totMarks);
}
}
Примечание в методе getKey
есть закомментированная строка кода с комментарием WRONG . Это относится к моему намеку на тестирование с однозначными баллами. Попробуйте поменять две строки кода, чтобы увидеть правильный и неправильный результат.
Вот главное, я удалил все элементы сканера - снова, чтобы облегчить мне жизнь. Надеюсь, вы сможете следить за этим и добавить его обратно в цикл сканирования.
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
public class StudentData {
public static void main(String[] args) {
// Initialise a list of students (as I don't want to rekey all the details each
// time I run the program).
List<Student> studentList = Arrays.asList(
new Student("Fred", 1, 2, 2, 2), /* Score of 6 */
new Student("John", 2, 2, 3, 3), /* Score of 8 */
new Student("Jane", 3, 20, 25, 30), /* Score of 75 */
new Student("Julie", 4, 20, 15, 10) /* Score of 45 */
// add as many new students as you like, and reorder them
// as much as you like to see if there is any difference in the
// result (there shouldn't be).
);
// Note the key of the tree is of type String - not Integer.
// This is the heart of the algorithm, the tree will be "sorted"
// on the natural key provided. This "natural key" is in fact
// a compound key that is generated by combining the total score
// and the student name.
Map<String,Student> map = new TreeMap<String,Student>();
for (Student ss : studentList) {
map.put(ss.getKey(),ss);
}
//stdList.forEach(System.out::print);
for(Map.Entry<String,Student> m :map.entrySet()) {
System.out.println(m);
}
}
}
Надеюсь, вы согласны с тем, что это более простое решение. Существует также потенциальное повышение производительности, поскольку студенты сортируются по мере их загрузки в дерево (т.е. один раз). Производительность этой сортировки, я думаю, log (n). Сортировка при извлечении, вероятно, будет n log (n) или хуже.