有没有办法使用 Comparator 来比较 Class 个对象的值?

Is there a way to compare values of Class objects using Comparator?

我们不能将比较器用于自定义 Class 或结构。我试图将 Student class 用作 Comparator 的参数,但似乎不起作用。知道如何在比较器的帮助下对 class 对象进行排序。 代码:

import java.util.*;

class Student {
    
    int id;
    String name;
    int marks[] = new int[5];

    public Student(int id, String name, int marks[]) {
        this.id = id;
        this.name = name;
        for (int i = 0; i < 5; i++) {
            this.marks[i] = marks[i];
        }
    }
}

class MarksSort {
    public static void main(String args[]) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        Student arr[] = new Student[n];

        for (int i = 0; i < n; i++) {

            int id = sc.nextInt();
            String name = sc.next();
            int marks[] = new int[5];

            for (int j = 0; j < 5; j++)
                marks[j] = sc.nextInt();
            arr[i] = new Student(id, name, marks);
        }

        int res[] = marksSort(n, arr);

        for (int j : res) {
            System.out.print(j + " ");
        }
    }

    static int[] marksSort(int n, Student arr[]) {
        int[] result = new int[n];
        
        Collections.sort(arr, new Comparator<Student> (){
            @Override public int compare(Student A, Student B){
                //will add sorting logic here
            }
        });
                
        return result;
    }}

    

我想在比较器中以这种方式排序。

  1. 总分最高的学生必须进入排行榜。
  2. 总分相同的学生将按姓名字母升序排序。
  3. 在所有其他情况下,id 较小的学生将在排行榜中排在前面

我得到的错误:-

Compile Error


MarksSort.java:46: error: no suitable method found for sort(Student[],<anonymous Comparator<Student>>)
Collections.sort(arr, new Comparator<Student> (){
^
method Collections.<T#1>sort(List<T#1>) is not applicable
(cannot infer type-variable(s) T#1
(actual and formal argument lists differ in length))
method Collections.<T#2>sort(List<T#2>,Comparator<? super T#2>) is not applicable
(cannot infer type-variable(s) T#2
(argument mismatch; Student[] cannot be converted to List<T#2>))
where T#1,T#2 are type-variables:
T#1 extends Comparable<? super T#1> declared in method <T#1>sort(List<T#1>)
T#2 extends Object declared in method <T#2>sort(List<T#2>,Comparator<? super T#2>)
1 error

Collections.sort用于对集合进行排序;你有一个数组;你必须使用 Arrays.sort。其次,你当然可以使用比较器中的便捷方法,这使得事情更容易编写并且启动时更具可读性:

Arrays.sort(arr, Comparator
  .comparingInt(Student::getMarkSum)
  .thenComparing(Student::getName)
  .thenComparingInt(Student::getId));

这正是它所说的:分数较低的学生比分数较晚的学生排在前面。为了区分具有相同分数的学生,使用他们的名字;为了区分具有相同分数和相同名称的学生,使用了 id。如果它仍然相同,则 2 在比较方面被认为是相等的。这意味着什么取决于数据结构。对于数组排序,这意味着它们将以任意顺序保留。例如TreeSet,这意味着如果与 TreeSet 相关联的比较器表示他们在比较器方面彼此相等,那么集合中不能有 2 个学生。

注意:您必须在您的 Student class 中创建方法 getIdgetMarkSumgetName,但这听起来像是您应该做的所以:Java 程序员通常会做吸气剂,所以,在罗马时,要像罗马人一样。如果你真的不想,你可以自由地在分拣机中实现它们,例如使用s -> s.id 而不是 Student::getId。重点是:您需要提供一个将学生对象转换为 int 或对象的函数。 Student::getId 是 java-ese 的原因:只需调用 getId() 方法即可。 s -> s.id 将是 java-ese 用于:获取 id 字段的值。你也可以把代码放在那里:

s -> {
    int sum = 0;
    for (int mark : s.marks.length) sum += mark;
    return sum;
};

作为 thenComparingInt 方法的参数。但是,如果您只是在 Student 本身中创建一个 getMarkSum 方法,它会使事情更具可读性和更容易测试:这将是正确的面向对象设计。