Aquí hay un tutorial sobre cómo ordenar objetos:
Aunque daré algunos ejemplos, recomendaría leerlo de todos modos.
Hay varias formas de ordenar un ArrayList
. Si desea definir un naturales (por defecto) de pedidos , a continuación, es necesario dejar que Contact
poner en práctica Comparable
. Suponiendo que desea ordenar de forma predeterminada name
, haga (se omiten las comprobaciones nulas para simplificar):
public class Contact implements Comparable<Contact> {
private String name;
private String phone;
private Address address;
public int compareTo(Contact other) {
return name.compareTo(other.name);
}
// Add/generate getters/setters and other boilerplate.
}
para que puedas hacer
List<Contact> contacts = new ArrayList<Contact>();
// Fill it.
Collections.sort(contacts);
Si desea definir un orden controlable externo (que anula el orden natural), entonces necesita crear un Comparator
:
List<Contact> contacts = new ArrayList<Contact>();
// Fill it.
// Now sort by address instead of name (default).
Collections.sort(contacts, new Comparator<Contact>() {
public int compare(Contact one, Contact other) {
return one.getAddress().compareTo(other.getAddress());
}
});
Incluso puede definir los Comparator
s en Contact
sí mismo para poder reutilizarlos en lugar de volver a crearlos cada vez:
public class Contact {
private String name;
private String phone;
private Address address;
// ...
public static Comparator<Contact> COMPARE_BY_PHONE = new Comparator<Contact>() {
public int compare(Contact one, Contact other) {
return one.phone.compareTo(other.phone);
}
};
public static Comparator<Contact> COMPARE_BY_ADDRESS = new Comparator<Contact>() {
public int compare(Contact one, Contact other) {
return one.address.compareTo(other.address);
}
};
}
que se puede utilizar de la siguiente manera:
List<Contact> contacts = new ArrayList<Contact>();
// Fill it.
// Sort by address.
Collections.sort(contacts, Contact.COMPARE_BY_ADDRESS);
// Sort later by phone.
Collections.sort(contacts, Contact.COMPARE_BY_PHONE);
Y para aclarar la parte superior, podría considerar usar un comparador de Java genérico :
public class BeanComparator implements Comparator<Object> {
private String getter;
public BeanComparator(String field) {
this.getter = "get" + field.substring(0, 1).toUpperCase() + field.substring(1);
}
public int compare(Object o1, Object o2) {
try {
if (o1 != null && o2 != null) {
o1 = o1.getClass().getMethod(getter, new Class[0]).invoke(o1, new Object[0]);
o2 = o2.getClass().getMethod(getter, new Class[0]).invoke(o2, new Object[0]);
}
} catch (Exception e) {
// If this exception occurs, then it is usually a fault of the developer.
throw new RuntimeException("Cannot compare " + o1 + " with " + o2 + " on " + getter, e);
}
return (o1 == null) ? -1 : ((o2 == null) ? 1 : ((Comparable<Object>) o1).compareTo(o2));
}
}
que puede utilizar de la siguiente manera:
// Sort on "phone" field of the Contact bean.
Collections.sort(contacts, new BeanComparator("phone"));
(como puede ver en el código, posiblemente los campos nulos ya estén cubiertos para evitar NPE durante la clasificación)
String.CASE_INSENSITIVE_ORDER
amigos, pero me gusta. Hace que el código resultante sea más fácil de leer.static
y quizásfinal
también ... O algo así ...(o1 == null && o2 == null) ? 0 :
al comienzo de esa línea de retorno?)Además de lo que ya se publicó debes saber que desde Java 8 podemos acortar nuestro código y escribirlo así:
o desde List ahora tiene
sort
métodoExplicación:
Desde Java 8, las interfaces funcionales (interfaces con un solo método abstracto; pueden tener más métodos predeterminados o estáticos) se pueden implementar fácilmente usando:
arguments -> body
source::method
.Dado que
Comparator<T>
solo tiene un método abstractoint compare(T o1, T o2)
, es una interfaz funcional.Entonces, en lugar de (ejemplo de la respuesta de @BalusC )
podemos reducir este código a:
Podemos simplificar esta (o cualquier) lambda saltando
{return
...}
Entonces en lugar de
podemos escribir
También ahora
Comparator
tiene métodos estáticos comocomparing(FunctionToComparableValue)
ocomparing(FunctionToValue, ValueComparator)
que podríamos usar para crear fácilmente comparadores que deberían comparar algunos valores específicos de objetos.En otras palabras, podemos reescribir el código anterior como
fuente
Esta página le dice todo lo que necesita saber sobre la clasificación de colecciones, como ArrayList.
Básicamente necesitas
Contact
clase implemente elComparable
interfazpublic int compareTo(Contact anotherContact)
dentro de él.Collections.sort(myContactList);
,myContactList
estáArrayList<Contact>
(o cualquier otra colección deContact
).También hay otra forma, que implica la creación de una clase Comparator, y también puede leer sobre eso en la página vinculada.
Ejemplo:
fuente
BalusC y bguiz ya han dado respuestas muy completas sobre cómo utilizar los comparadores integrados de Java.
Solo quiero agregar que google-collections tiene una clase Ordering que es más "poderosa" que los comparadores estándar. Podría valer la pena echarle un vistazo. Puede hacer cosas interesantes, como componer ordenaciones, invertirlas, ordenar según el resultado de una función para sus objetos ...
Aquí hay una publicación de blog que menciona algunos de sus beneficios.
fuente
Necesita hacer que sus clases de contacto implementen Comparable y luego implementar el
compareTo(Contact)
método. De esa manera, Collections.sort podrá ordenarlos por usted. Según la página a la que me vinculé, compareTo 'devuelve un número entero negativo, cero o un número entero positivo ya que este objeto es menor, igual o mayor que el objeto especificado'.Por ejemplo, si quisiera ordenar por nombre (de la A a la Z), su clase se vería así:
fuente
Al usar lambdaj , puede ordenar una colección de sus contactos (por ejemplo, por su nombre) de la siguiente manera
o por su dirección:
y así. Más en general, ofrece un DSL para acceder y manipular sus colecciones de muchas formas, como filtrar o agrupar sus contactos en función de algunas condiciones, agregar algunos de sus valores de propiedad, etc.
fuente
Collections.sort es una buena implementación de ordenación. Si no tiene implementado el comparable para el contacto, deberá pasar una implementación del comparador
De nota:
La clasificación por combinación es probablemente mejor que la mayoría de los algoritmos de búsqueda que puede hacer.
fuente
Lo hice de la siguiente manera. número y nombre son dos listas de arrays. Tengo que ordenar el nombre. Si se produce algún cambio en el orden de la lista de matrices de nombres, la lista de matrices de números también cambiará su orden.
fuente
usa este método:
'
y uso:
mySortedlist = sortList(myList);
No es necesario implementar comparador en su clase. Si desea un intercambio de orden inverso1
y-1
fuente
Ok, sé que esto fue respondido hace mucho tiempo ... pero, aquí hay información nueva:
Supongamos que la clase de contacto en cuestión ya tiene un orden natural definido mediante la implementación de Comparable, pero desea anular ese orden, por ejemplo, por nombre. Esta es la forma moderna de hacerlo:
De esta manera, primero ordenará por nombre (en orden inverso), y luego, para las colisiones de nombres, recurrirá al orden "natural" implementado por la propia clase Contact.
fuente
Debe utilizar la función Arrays.sort. Las clases contenedoras deben implementar Comparable.
fuente