Java Collections.sort()未按预期排序

Mar*_*uer 6 java sorting collections comparable comparator

我试图通过特定的属性("程序"的"学生"对象和"教师"的"教授"对象)对对象的两个不同的数组列表进行排序.这两个类都扩展了我的抽象'Person'类.

public abstract class Person implements Comparable<Person>{
    private String name;
    private String adress;

    //getters, setters, etc., all works properly

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone(); 
    }

    public int compareTo(String string) {
        return name.compareTo(string);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,当我创建一个1000000个随机"人物"对象的数组而不是学生或教授时,我决定按照它们的名字(按字母顺序)按字母顺序排序(它可以正常工作).

Person personByName[] = arrayPersonas.clone();
Arrays.sort(personByName);
Run Code Online (Sandbox Code Playgroud)

然后,我将原始Person数组分成两个ArrayLists,一个用于Student对象,另一个用于Professor对象:

    ArrayList<Student> studentsByProgram = new ArrayList();
    ArrayList<Professor> professorsByFaculty = new ArrayList();
    for (int i = 0; i < 1000000; i++) { 
        if (arrayPersonas[i] instanceof Student) {
            studentsByProgram.add((Student)arrayPersonas[i]);
        } else {
            professorsByFaculty.add((Professor)arrayPersonas[i]);
        }
    }
Run Code Online (Sandbox Code Playgroud)

当我尝试按照我想要的属性按字母顺序对每个ArrayList进行排序时会出现问题,因为它会按Person的名称对它们进行排序:

Collections.sort(studentsByProgram);
Collections.sort(professorsByFaculty);
Run Code Online (Sandbox Code Playgroud)

在这里,我留下我的学生和教授课程:

public class Student extends Person {
    private String program;
    private int year;
    private double fee;

    //constructor, setters, getters, toString, equals

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone(); 
    }



    public int compareTo(String string) {
        return program.compareTo(string); 
    }

    @Override
    public int compareTo(Person t) {
        return super.compareTo(t.getName());
    }
}
Run Code Online (Sandbox Code Playgroud)

教授班:

public class Professor extends Person {
    private String faculty;
    private double salary;

    //constructor, setters, getters, toString, equals

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone(); 
    }


    public int compareTo(String string) {
        return faculty.compareTo(string); 
    }

    @Override
    public int compareTo(Person t) {
        return super.compareTo(t.getName());
    }
}
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?我想如果我在Student对象的ArrayList上调用"Collections.sort()",它将使用我的Student类中的"compareTo()"方法,该方法使用"program"属性.我还在学习使用这些方法,所以有些东西我没有得到.

And*_*lko 1

存在的问题

  1. 您没有定义如何Person比较对象。
  2. 您错误地定义了如何比较Student和实例。Professor
  3. 您编写了compareTo(String)具有误导性的重载方法。

解决方案

  1. 正确定义Person#compareTo,删除其compareTo(String)

    public int compareTo(Person p) {
        return getName().compareTo(p.getName());
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 定义Student#compareToProfessor#compareTo正确删除它们compareTo(String)Student#compareTo下面是如何编写的示例:

    @Override
    public int compareTo(Person t) {
        final int personComparisonResult = super.compareTo(t);
    
        if (personComparisonResult == 0) {
            return program.compareTo(((Student) t).program);
        }
    
        return personComparisonResult;
    }
    
    Run Code Online (Sandbox Code Playgroud)

    它说“首先将它们与Persons 进行比较;如果它们相等(此处,具有相同的名称),则将它们与Students 进行比较(此处,按学生的程序)”。

  3. 我会删除这些方法。对于不适合类域的简单代码行使用单独的方法是不值得的。