Ejemplo con Google Guava Comparator
De Dos Ideas.
Objetivo
- Encontrar una manera de organizar listas de una determinada entidad, por un conjunto de campos específico, de manera de poder tener múltiples criterios de ordenamiento sobre la misma clase.
Situación ejemplo
- Tenemos una clase Tarea
- Tarea está asociada a un Usuario
- Tarea tiene una fecha.
- Usuario tiene dos String que representan el nombre y apellido respectivamente.
- Tenemos que ordenar una List<Tarea> , por apellido y nombre del usuario relacionado, y fecha de la tarea.
SIN Guava
- Deberíamos crear una clase TareaComparator que implemente Comparator<Tarea>,
poniendo en el siguiente método:
@Override public int compare(Tarea t1, Tarea t2) { //código armando el criterio de ordenamiento de cada tarea //aca se deberia armar/concatenar todos los criterios en uno solo, obteniendo tareaCriterio1 y tareaCriterio2 return tareaCriterio1.compareTo(tareaCriterio2); }
- Luego en nuestro código de negocio, al momento de ordenar deberíamos invocar a Collections.sort(lista, tareaComparator)
- De dicha manera, si quisiéramos tener otro criterio de ordenamiento, deberíamos tener una clase por cada criterio distinto de ordenamiento.
CON librerías de [Guava ]
- Crear la clase TareaComparator, sin implementar ninguna interfaz.
/** * Constructor privado. */ private TareaComparator() { } /** * Ordena tarea por nombre de usuario. */ private static Comparator<Tarea> byNombre = new Comparator<Tarea>() { @Override public int compare(final Tarea p1, final Tarea p2) { return p1.getUsuario().getNombre().compareTo(p2.getUsuario().getNombre()); } }; /** * Ordena tarea por apellido de usuario. */ private static Comparator<Tarea> byApellido = new Comparator<Tarea>() { @Override public int compare(final Tarea p1, final Tarea p2) { return p1.getUsuario().getApellido().compareTo(p2.getUsuario().getApellido()); } }; /** * Ordena tarea por fecha. */ private static Comparator<Tarea> byFecha = new Comparator<Tarea>() { @Override public int compare(final Tarea p1, final Tarea p2) { return p1.getFecha().compareTo(p2.getFecha()); } }; /** * @return byNombre */ public static Comparator<Tarea> getByNombre() { return byNombre; } /** * @return byApellido */ public static Comparator<Tarea> getByApellido() { return byApellido; } /** * @return byFecha */ public static Comparator<Tarea> getByFecha() { return byFecha; }
- Luego en nuestro código de negocio, al momento de ordenar deberíamos usar:
List<Tarea> tareasOrdenadas = Ordering.from(TareaComparator.getByApellido()) .compound(TareaComparator.getByNombre()) .compound(TareaComparator.getByFecha()) .sortedCopy(tareasDesordenadas);
- De esta manera, podemos anidar criterios de ordenamiento, combinándolos de las maneras que necesitemos, teniendo las comparaciones agrupadas en una sola clase.