Tengo una variedad de objetos person (int age; String name;)
.
¿Cómo puedo ordenar esta matriz alfabéticamente por nombre y luego por edad?
¿Qué algoritmo usarías para esto?
Puedes usar Collections.sort
lo siguiente:
private static void order(List<Person> persons) {
Collections.sort(persons, new Comparator() {
public int compare(Object o1, Object o2) {
String x1 = ((Person) o1).getName();
String x2 = ((Person) o2).getName();
int sComp = x1.compareTo(x2);
if (sComp != 0) {
return sComp;
}
Integer x1 = ((Person) o1).getAge();
Integer x2 = ((Person) o2).getAge();
return x1.compareTo(x2);
}});
}
List<Persons>
ahora está ordenado por nombre, luego por edad.
String.compareTo
"Compara dos cadenas lexicográficamente" - de los documentos .
Collections.sort
es un método estático en la biblioteca de colecciones nativa. Realiza la clasificación real, solo necesita proporcionar un comparador que defina cómo deben compararse dos elementos de su lista: esto se logra al proporcionar su propia implementación del compare
método.
Comparator
para evitar tener que emitir las entradas.Comparable
. Ver la respuesta de @ berry120Comparator<Person> comparator = Comparator.comparing(Person::getName).thenComparingInt(Person::getAge);
Para aquellos que pueden usar la API de transmisión Java 8, hay un enfoque más ordenado que está bien documentado aquí: Lambdas y clasificación
Estaba buscando el equivalente de C # LINQ:
Encontré el mecanismo en Java 8 en el Comparador:
Así que aquí está el fragmento que demuestra el algoritmo.
Consulte el enlace de arriba para obtener una forma más ordenada y una explicación sobre cómo la inferencia de tipos de Java hace que sea un poco más complicado de definir en comparación con LINQ.
Aquí está la prueba de unidad completa para referencia:
fuente
Comparator<Person> comparator = Comparator.comparing(Person::getName).thenComparing(Person::getAge);
thenComparingInt
for age (int)Collections.sort(people, comparator);
en su lugar?Uso del enfoque de Java 8 Streams ...
Y el enfoque Java 8 Lambda ...
Por último...
fuente
Debe implementar el suyo
Comparator
y luego usarlo: por ejemploSu comparador podría verse un poco así:
El comparador primero compara los nombres; si no son iguales, devuelve el resultado de compararlos; de lo contrario, devuelve el resultado de comparación al comparar las edades de ambas personas.
Este código es solo un borrador: debido a que la clase es inmutable, se podría pensar en construir un singleton de ella, en lugar de crear una nueva instancia para cada clasificación.
fuente
Puede utilizar el enfoque Java 8 Lambda para lograr esto. Me gusta esto:
fuente
Haga que su clase de persona implemente
Comparable<Person>
y luego implemente el método compareTo, por ejemplo:Eso se ordenará primero por nombre (sin distinción entre mayúsculas y minúsculas) y luego por edad. Luego puede ejecutar
Arrays.sort()
oCollections.sort()
en la colección o matriz de objetos Persona.fuente
La guayaba
ComparisonChain
proporciona una forma limpia de hacerlo. Consulte este enlace .Una utilidad para realizar una declaración de comparación encadenada. Por ejemplo:
fuente
Puedes hacer así:
fuente
Use
Comparator
y luego ponga objetosCollection
, luegoCollections.sort();
fuente
Crea tantos comparadores como sea necesario. Después, llame al método "thenComparing" para cada categoría de pedido. Es una forma de hacerlo por Streams. Ver:
Aspecto: ordenar objetos definidos por el usuario en múltiples campos - Comparador (secuencia lambda)
fuente
Sería cuidadoso al usar Guava's
ComparisonChain
porque crea una instancia de él por elemento comparado, por lo que estaría viendo una creación deN x Log N
cadenas de comparación solo para comparar si está ordenando, oN
instancias si está iterando y verificando la igualdad.En su lugar, crearía una estática
Comparator
utilizando la API de Java 8 más nueva si es posible o laOrdering
API de Guava que le permite hacer eso, aquí hay un ejemplo con Java 8:Aquí se explica cómo usar la
Ordering
API de Guava : https://github.com/google/guava/wiki/OrderingExplainedfuente
compare
método no crea nada, pero devuelve una de las instancias singletonLESS
,GREATER
oACTIVE
dependiendo del resultado de la comparación. Este es un enfoque altamente optimizado y no agrega memoria ni sobrecarga de rendimiento.O puede explotar el hecho de que
Collections.sort()
(oArrays.sort()
) es estable (no reordena elementos que son iguales) y use unComparator
para ordenar por edad primero y luego otro para ordenar por nombre.En este caso específico, esta no es una muy buena idea, pero si tiene que poder cambiar el orden de clasificación en tiempo de ejecución, podría ser útil.
fuente
Puede usar el comparador en serie genérico para ordenar las colecciones por múltiples campos.
fuente
Versión actualizada:
fuente
Para una clase
Book
como esta:ordenar la clase principal con objetos simulados
fuente
No estoy seguro de si es feo escribir el compartimento dentro de la clase Persona en este caso. Lo hizo así:
fuente