Ordenar un List<> ArrayList de objetos
Esta ocasión explicaré como ordenar una lista de tipo arraylist de objetos predeterminados.
Tengo mi clase del objeto Empleado.
public class Empleado implements Comparable<Empleado> {
private String nombre;
private int edad;
private String domicilio;
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
public int getEdad() {
return edad;
}
public void setEdad(int edad) {
this.edad = edad;
}
public String getDomicilio() {
return domicilio;
}
public void setDomicilio(String domicilio) {
this.domicilio = domicilio;
}
@Override
public int compareTo(Empleado o) {
String a=new String(String.valueOf(this.getEdad())+this.getNombre());
String b=new String(String.valueOf(o.getEdad())+o.getNombre());
return a.compareTo(b);
}
}
Observese la linea donde aparece el compareTo(), este método me permitirá ordenar mi lista según el criterio especifico. (Primero por Edad luego por Nombre).
Observese String.valueOf(), este me permite cambiar el formato del valor, en primera instancia la Edad que de ser int pasa a String, luego el Nombre sigue siendo String.
Despues tengo la clase que trabaja la lista List<> sin orden especifico.
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
public class Ordenar {
public static void main(String args[])throws IOException{
List<Empleado> listaEmpleados=new ArrayList<Empleado>();
//creamos los objetos para llenar la lista
Empleado empleado1=new Empleado();
Empleado empleado2=new Empleado();
Empleado empleado3=new Empleado();
empleado1.setNombre("Ramon");
empleado1.setEdad(30);
empleado1.setDomicilio("Galerías 104, Versalles 1era sec.");
empleado2.setNombre("Toño");
empleado2.setEdad(28);
empleado2.setDomicilio("Ojo de Agua 101, Ojo Caliente X.");
empleado3.setNombre("Aramíz");
empleado3.setEdad(30);
empleado3.setDomicilio("Cosio 203, Zona Centro");
listaEmpleados.add(empleado1);//los metemos a la lista
listaEmpleados.add(empleado2);
listaEmpleados.add(empleado3);
//creamos el iterator para recorrer la lista sin ordenar
Iterator itListaempleado=listaEmpleados.iterator();
//imprime la lista sin ordenar
while (itListaempleado.hasNext()) {
Empleado elementoLista=(Empleado)itListaempleado.next();
System.out.println(elementoLista.getNombre()+" "+elementoLista.getEdad()+" "+elementoLista.getDomicilio());
}
}
}
Ejecuto la secuencia y la consola arroja lo siguiente.
Ramon 30 Galerías 104, Versalles 1era sec.
Toño 28 Ojo de Agua 101, Ojo Caliente X.
Aramíz 30 Cosio 203, Zona Centro
BUILD SUCCESSFUL (total time: 1 second)
Hasta aquí la lista contiene los elementos en el orden en el que se fueron agregando a la lista, si queremos ordenarlos, hay que disparar el método Collections.sort() que lo va lograr basándose en @Override de la clase del Objeto de la lista.
Antes de imprimir la lista nuevamente, hay que ordenarlo...
Se ejecuta el @Override comparable() del objeto que ocupa los espacios de la lista.
Ahora la impresión es esta.
Toño 28 Ojo de Agua 101, Ojo Caliente X.
Aramíz 30 Cosio 203, Zona Centro
Ramon 30 Galerías 104, Versalles 1era sec.
BUILD SUCCESSFUL (total time: 1 second)
Espero les sirva.
- nomarlegnar's blog
- Inicie sesión o regístrese para enviar comentarios
Comentarios
No conviertas a String para
No conviertas a String para comparar, puedes comparar directamente por campos.
Con tu implementación si las edades son 1, 2 y 10 respectivamente la salida es:
Aramíz 10 Cosio 203, Zona Centro
Ramon 1 Galerías 104, Versalles 1era sec.
Toño 2 Ojo de Agua 101, Ojo Caliente X.
Que parece más desordenado aún.
En el método compareTo compara por cada campo, primero por edad y si son iguales entonces por nombre.
Quería poner un ejemplo más sencillo, pero comparar por edad / nombre no es taaaaaan trivial como parece.
Esta sería la versión correcta de compareTo
public int compareTo( Empleado o ) {
int byAge = Integer.compare(edad, o.edad);
if ( byAge != 0 ) {
return byAge;
}
if ( nombre == null ) {
return o.nombre == null ? 0 : 1;
}
if ( o.nombre == null ) {
return 1;
}
return nombre.compareToIgnoreCase(o.nombre);
}
...
Ramon 1 Galerías 104, Versalles 1era sec.
Toño 1 Ojo de Agua 101, Ojo Caliente X.
Aramíz 10 Cosio 203, Zona Centro
Oh, claro...
Cuando la ordenación es únicamente por valores numéricos esto que comentas es lo mas correcto.
La representación de la ordenación que comentas que no es taaaan trivial pues efectivamente no lo es, pero cuando te topas con un tema de sucursales por entidad ahí entra lo que apliqué, lo que funcionó y lo que cumplo con compartir, tu comentario complementa perfectamente lo que quería explicar.
Eh visto a lo que te referías con lo del 1 y del 10 al cambiarlos a String efectivamente tiene ese efecto que comentas. Mas que ordenarlos los desordena.
:S
Me hubiera sido mas atinado manejar un ejemplo sobre apellido paterno, materno y nombre ahora que lo pienso...
Jeje, si, esa es la idea
Jeje, si, esa es la idea tener una comunidad, alguien escribe algo y alguien más opina o comenta al respecto y todo mundo se beneficia de ello.
Manita Arriba
Si, la comunidad es para eso! Yeah !
Como ejercicio me gusto pero.
Me gusto pues dejas muy claro el uso de los elementos, pero seria bueno que mencionaras TreeSet ( http://docs.oracle.com/javase/7/docs/api/java/util/TreeSet.html ), pues es una clase que resuelve sola el ordenamiento.
Saludos.
TreeSet
Pero consideren que TreeSet es un Set, por lo que no permite elementos duplicados, a diferencia de una lista, que sí los permite.
Por si acaso
No lo recuerdo muy bien pero había problemas cuando comparabas Strings con acentos o caracteres especiales desde alguna versión de java.
Se los comento para que no olviden este caso en sus pruebas.