Ordenar ArrayList de objetos personalizados por propiedad

Resuelto Samuel asked hace 14 años • 29 respuestas

Leí acerca de ordenar ArrayLists usando un Comparador, pero en todos los ejemplos la gente usó compareTolo que, según algunas investigaciones, es un método para cadenas.

Quería ordenar una ArrayList de objetos personalizados por una de sus propiedades: un objeto Fecha ( getStartDay()). Normalmente los comparo así item1.getStartDate().before(item2.getStartDate())que me preguntaba si podría escribir algo como:

public class CustomComparator {
    public boolean compare(Object object1, Object object2) {
        return object1.getStartDate().before(object2.getStartDate());
    }
}

public class RandomName {
    ...
    Collections.sort(Database.arrayList, new CustomComparator);
    ...
}
Samuel avatar May 07 '10 04:05 Samuel
Aceptado

Dado que Datese implementa Comparable, tiene un compareTométodo como Stringel que tiene.

Entonces tu costumbre Comparatorpodría verse así:

public class CustomComparator implements Comparator<MyObject> {
    @Override
    public int compare(MyObject o1, MyObject o2) {
        return o1.getStartDate().compareTo(o2.getStartDate());
    }
}

El compare()método debe devolver un int, por lo que no podrías devolver directamente un booleancomo estabas planeando hacerlo de todos modos.

Su código de clasificación sería casi como usted escribió:

Collections.sort(Database.arrayList, new CustomComparator());

Una forma un poco más corta de escribir todo esto, si no necesita reutilizar su comparador, es escribirlo como una clase anónima en línea:

Collections.sort(Database.arrayList, new Comparator<MyObject>() {
    @Override
    public int compare(MyObject o1, MyObject o2) {
        return o1.getStartDate().compareTo(o2.getStartDate());
    }
});

Desdejava-8

Ahora puede escribir el último ejemplo en una forma más breve utilizando una expresión lambda para Comparator:

Collections.sort(Database.arrayList, 
                        (o1, o2) -> o1.getStartDate().compareTo(o2.getStartDate()));

Y Listtiene un sort(Comparator)método, por lo que puedes acortarlo aún más:

Database.arrayList.sort((o1, o2) -> o1.getStartDate().compareTo(o2.getStartDate()));

Este es un modismo tan común que hay un método incorporado para generar Comparatoruna clase con una Comparableclave:

Database.arrayList.sort(Comparator.comparing(MyObject::getStartDate));

Todas estas son formas equivalentes.

Michael Myers avatar May 06 '2010 21:05 Michael Myers

Las clases que tienen un orden de clasificación natural (una clase Número, por ejemplo) deben implementar la interfaz Comparable, mientras que las clases que no tienen un orden de clasificación natural (una clase Presidente, por ejemplo) deben recibir un Comparador (o un Comparador anónimo). clase).

Dos ejemplos:

public class Number implements Comparable<Number> {
    private int value;

    public Number(int value) { this.value = value; }
    public int compareTo(Number anotherInstance) {
        return this.value - anotherInstance.value;
    }
}

public class Chair {
    private int weight;
    private int height;

    public Chair(int weight, int height) {
        this.weight = weight;
        this.height = height;
    }
    /* Omitting getters and setters */
}
class ChairWeightComparator implements Comparator<Chair> {
    public int compare(Chair chair1, Chair chair2) {
        return chair1.getWeight() - chair2.getWeight();
    }
}
class ChairHeightComparator implements Comparator<Chair> {
    public int compare(Chair chair1, Chair chair2) {
        return chair1.getHeight() - chair2.getHeight();
    }
}

Uso:

List<Number> numbers = new ArrayList<Number>();
...
Collections.sort(numbers);

List<Chair> chairs = new ArrayList<Chair>();
// Sort by weight:
Collections.sort(chairs, new ChairWeightComparator());
// Sort by height:
Collections.sort(chairs, new ChairHeightComparator());

// You can also create anonymous comparators;
// Sort by color:
Collections.sort(chairs, new Comparator<Chair>() {
    public int compare(Chair chair1, Chair chair2) {
        ...
    }
});
Björn avatar May 06 '2010 21:05 Björn

Para ordenar, ArrayListpuede utilizar el siguiente fragmento de código:

Collections.sort(studList, new Comparator<Student>(){
    public int compare(Student s1, Student s2) {
        return s1.getFirstName().compareToIgnoreCase(s2.getFirstName());
    }
});
 avatar May 06 '2012 13:05