Tengo una clase nombrada Person
con múltiples propiedades, por ejemplo:
public class Person {
private int id;
private String name, address;
// Many more properties.
}
Muchos Person
-objetos se almacenan en un archivo ArrayList<Person>
. Quiero ordenar esta lista por múltiples parámetros de ordenación y diferentes de vez en cuando. Por ejemplo, una vez podría querer ordenar name
ascendiendo y luego address
descendiendo, y otra vez simplemente id
descendiendo.
Y no quiero crear mis propios métodos de ordenación (es decir, quiero usar Collections.sort(personList, someComparator)
. ¿Cuál es la solución más elegante que lo logra?
comparator.reversed()
para descender y se puede utilizarcomparator1.thenComparing(comparator2)
para encadenar comparadores.Puede crear comparadores para cada una de las propiedades que desee ordenar y luego probar el "encadenamiento de comparadores" :-) así:
fuente
Una forma es crear un
Comparator
que tome como argumentos una lista de propiedades para ordenar, como muestra este ejemplo.Luego se puede usar en código, por ejemplo, como este:
fuente
Un enfoque sería componer
Comparator
s. Este podría ser un método de biblioteca (estoy seguro de que existe en algún lugar).Utilizar:
Alternativamente, tenga en cuenta que
Collections.sort
es un tipo estable. Si el rendimiento no es absolutamente crucial, ordena ser el orden secundario antes que el primario.fuente
compose(nameComparator, compose(addressComparator, idComparator))
Eso se leería un poco mejor si Java tuviera métodos de extensión.Los comparadores le permiten hacerlo de manera muy fácil y natural. Puede crear instancias únicas de comparadores, ya sea en su propia clase Person o en una clase de Servicio asociada a su necesidad.
Ejemplos, usando clases internas anónimas:
Si tiene muchos, también puede estructurar el código de sus comparadores de la forma que desee. Por ejemplo, podrías:
fuente
Creo que acoplar los clasificadores a la clase Person, como en su respuesta, no es una buena idea, porque empareja la comparación (generalmente impulsada por el negocio) y el objeto modelo para acercarse entre sí. Cada vez que desee cambiar / agregar algo al clasificador, debe tocar la clase de persona, que generalmente es algo que no desea hacer.
Usar un servicio o algo similar, que proporciona instancias de Comparator, como el propuesto por KLE, suena mucho más flexible y extensible.
fuente
Mi enfoque se basa en el de Yishai. La principal brecha es que no hay forma de ordenar primero ascendente por un atributo y luego descendente por otro. Esto no se puede hacer con enumeraciones. Para eso usé clases. Debido a que SortOrder depende en gran medida del tipo, preferí implementarlo como una clase interna de persona.
La clase 'Persona' con la clase interna 'SortOrder':
Un ejemplo para usar la clase Person y su SortOrder:
oRUMOo
fuente
Recientemente escribí un Comparador para ordenar varios campos dentro de un registro de cadena delimitado. Le permite definir el delimitador, la estructura del registro y las reglas de clasificación (algunas de las cuales son específicas del tipo). Puede usar esto convirtiendo un registro de persona en una cadena delimitada.
La información requerida se inserta en el propio Comparador, ya sea mediante programación o mediante un archivo XML.
XML es validado por un paquete de archivo XSD integrado. Por ejemplo, a continuación se muestra un diseño de registro delimitado por tabuladores con cuatro campos (dos de los cuales se pueden ordenar):
Luego usaría esto en java así:
La biblioteca se puede encontrar aquí:
http://sourceforge.net/projects/multicolumnrowcomparator/
fuente
Supongamos que hay una clase
Coordinate
y uno tiene que ordenarla de ambas formas según la coordenada X y la coordenada Y. Para ello se necesitan dos comparadores diferentes. A continuación se muestra la muestrafuente