Ordenación de colecciones mediante la interfaz Comparable
int compareTo(Object o);
Este método tiene que devolver un valor negativo si éste objeto es menor que el recibido, 0 si son iguales o un valor positivo si es mayor, según el orden natural de los objetos, que en muchos casos habrá que especificar.
Por ejemplo, para una clase persona, podría interesar ordenar por dni, o por apellidos y nombre, o por nombres y apellidos, etc.
public class Persona implements Comparable {
private String nombre;
private String apellidos;
private String dni;
private Date fechaNacimiento;
…
public int compareTo(Object o) {
Persona persona =
(Persona)o;
if(this.apellidos.compareToIgnoreCase(persona.apellidos) == 0)
{
if(this.nombre.compareToIgnoreCase(persona.nombre) == 0) {
return this.dni.compareTo(persona.dni);
} else {
return this.nombre.compareToIgnoreCase(persona.nombre);
}
} else {
return
this.apellidos.compareToIgnoreCase(persona.apellidos);
}
}
} // Compara por apellidos, nombre
y dni
…
public int compareTo(Object o) {
Persona persona =
(Persona)o;
return this.dni.compareTo(persona.dni);
} // Compara sólo por el dni
Una vez que tuviéramos una lista con datos, en este caso Personas, la ordenaríamos con la clase java.util.Collections, de la siguiente forma:
Collections.sort(lista);
Este método puede ordenar cualquier colección que implemente el interface java.util.List, según el orden que indica el método comparteTo.
Ordenación de listas y colecciones mediante la interfaz
Comparator
Ordenación de listas (vectores)
int listaEnteros [] = {2, 1, 5, 6, 8, 3, 56, 42};
Arrays.sort(listaEnteros);
String listaStrings [] = {“Ana”, “Pablo”,
“Marcos”, “Rosa”, “Lucas”, “Sara”, “Marta”, “Pedro”};
Arrays.sort(listaStrings);
Por último, también se podría hacer para listas de objetos que tengan una clase comparador que implemente la interfaz comparator (y que por tanto defina cómo se comparan dos objetos de tipo Persona). Supongamos que la clase ComparadorPersona, implementa comparator. Se utilizaría así:
public class ComparadorPersona implements Comparator<Persona>{
@Override
public
int compare(Persona o1, Persona o2) {
return o1.getApellido1().compareToIgnoreCase(o2.getApellido1());
}
}
…
Persona listaPersonas [] = new Persona[50];
Arrays.sort(listaPersonas,
new ComparadorPersona()); //compara por el primer apellido
En lugar de utilizar un comparador propio se podría utilizar
el método comparing de la interfaz Comparator. De esta forma:
Comparator<Persona> cp=
Comparator.comparing(Persona::getApellido2);
Arrays.sort(listaPersonas, cp); //compara
por el segundo apellido
Se pueden incluso encadenar los campos por los que comparar.
En el siguiente ejemplo se compara por el primer apellido, por el segundo y por
el nombre.
Comparator<Persona> cp2= Comparator.comparing(Persona::getApellido1).
thenComparing(Persona::getApellido2).thenComparing(Persona::getNombre);
Arrays.sort(listaPersonas, cp2);
También se puede hacer que la comparación sea en orden
descendente:
Comparator<Persona> cp3= Comparator.comparing(Persona::getApellido1).reversed();
Arrays.sort(listaPersonas, cp3); //compara por el primer apellido en orden descendente
Ordenación de colecciones
La ventaja que presenta la interfaz Comparator, es que permite ordenar colecciones por distintos campos en diferentes momentos. La solución es crear distintas clases que implementen la interfaz Comparator, cada una que ordene de forma distinta, para después poder usarlas cuando convenga. Después podremos utilizar Collections.sort(), pero pasándole como segundo argumento un comparador.
import
java.util.Comparator; // CompFichaDni.java
public class CompFichaDni
implements Comparator<Ficha>{
@Override
public int compare(Ficha o1, Ficha o2){
return
o1.getDni().compareTo(o2.getDni());
}
}
import
java.util.Comparator; // CompFichaNota.java
public class
CompFichaNota implements Comparator<Ficha>{
@Override
public int compare(Ficha o1, Ficha o2){
return (o1.getNota()>o2.getNota() ?
1 : o1.getNota()==o2.getNota() ? 0 :-1);
}
}
Después se utilizaría de esta forma:
System.out.println("\n Ordenados por dni:");
Collections.sort(lista,
new CompFichaDni());
…
System.out.println("\n Ordenados por nota:");
Collections.sort(lista, new CompFichaNota());
En lugar de crear una clase que implemente la interfaz,
también se pueden crear comparadores directamente a partir de la interfaz y de
los métodos de acceso. Supongamos una colección de personas que queremos
ordenar por distintos atributos. Ejemplo: