Java Collections.sort () no sorting como se esperaba

Marc Brauer:

Estoy tratando de resolver dos ArrayLists diferentes de objetos por un atributo específico (objetos 'estudiante' por "programa" y objetos 'profesor' por "facultad"). Ambas clases se extienden mi clase abstracta 'persona'.

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);
    }
}

Entonces, cuando se crea un conjunto de objetos al azar 1000000 'persona' que pueden ser estudiantes o profesores, decido ordenarla alfabéticamente por su nombre como esto (que funciona correctamente).

Person personByName[] = arrayPersonas.clone();
Arrays.sort(personByName);

Entonces, divido la matriz persona original en dos ArrayLists, uno para objetos Student y otro para el profesor objetos:

    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]);
        }
    }

El problema viene cuando intento ordenar cada ArrayList alfabéticamente por el atributo que quiera, ya que mantiene la clasificación por el nombre de la persona:

Collections.sort(studentsByProgram);
Collections.sort(professorsByFaculty);

Aquí les dejo mis clases de estudiantes y profesores:

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());
    }
}

clase Profesor:

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());
    }
}

¿Qué estoy haciendo mal? Pensé que si yo llamo "Collections.sort ()" en un ArrayList de objetos Student sería utilizar el método "compareTo ()" de mi clase del estudiante, que utiliza el atributo "programa". Todavía estoy aprendiendo a trabajar con estos métodos por lo que no es algo que yo no recibo.

Andrew Tobilko:

Los problemas

  1. Que no define cómo Personse deben comparar objetos.
  2. Usted definidos de forma incorrecta la forma Studenty Professorlos casos se debe comparar.
  3. Usted escribió métodos sobrecargados compareTo(String)que son engañosos.

Las soluciones

  1. Definir Person#compareTocorrectamente, retire su compareTo(String):

    public int compareTo(Person p) {
        return getName().compareTo(p.getName());
    }
    
  2. Definir Student#compareToy Professor#compareTocorrectamente, retire su compareTo(String). Aquí está un ejemplo de cómo Student#compareTose podría escribir:

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

    Dice que "comparar como Persons primeros; si son iguales (en este caso, tener el mismo nombre), ellos se compara como Students (en este caso, por el programa del estudiante)".

  3. Me gustaría eliminar estos métodos. No vale la pena tener un método diferente para una simple línea de código que no encaja en el dominio de clase.

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=173805&siteId=1
Recomendado
Clasificación