El uso del interface Java Comparator es muy común cuando trabajamos con Java . En muchas ocaciones tenemos que ordenar una lista de elementos y usamos el interface Comparator para hacerlo . Hasta la llegada de Java 8 comparar elementos siempre ha sido bastante engorroso . Vamos a ver un ejemplo clásico para luego evolucionarle con Java 8. Para ello partiremos de una lista de Personas.
package com.arquitecturajava.ejemplo1; public class Persona { private String nombre; private String apellido1; private String apellido2; public String getNombre() { return nombre; } public void setNombre(String nombre) { this.nombre = nombre; } public String getApellido1() { return apellido1; } public void setApellido1(String apellido1) { this.apellido1 = apellido1; } public String getApellido2() { return apellido2; } public void setApellido2(String apellido2) { this.apellido2 = apellido2; } public Persona(String nombre, String apellido1, String apellido2) { super(); this.nombre = nombre; this.apellido1 = apellido1; this.apellido2 = apellido2; } @Override public String toString() { return "Persona [nombre=" + nombre + ", apellido1=" + apellido1 + ", apellido2=" + apellido2 + "]"; } }
Java Comparator e Interfaces
Vamos a crearnos una lista de Personas que deseamos ordenar. Esta lista puede ser ordenada de diversas formas. Por ejemplo por nombre , apellido1 o apellido2.
package com.arquitecturajava.ejemplo1; import java.util.Arrays; import java.util.List; public class Principal2 { public static void main(String[] args) { // TODO Auto-generated method stub Persona p1= new Persona("pedro","perez","gomez"); Persona p2= new Persona("angel","alvarez","zamora"); Persona p3= new Persona("ana","perez","jimenez"); Persona p4= new Persona("ana","sainz","jimenez"); Persona p5= new Persona("maria","alvarez","alvarez"); List<Persona> lista=Arrays.asList(p1,p2,p3,p4,p5); } }
Java Comparator implementación
Para ordenar la lista necesitaremos implementar un Java Comparator que decida de que forma se va a comparar cada elemento.
En nuestro caso la primera comparación que deseamos es la de nombre.
package com.arquitecturajava.ejemplo1; import java.util.Comparator; public class ComparadorNombre implements Comparator<Persona> { @Override public int compare(Persona p1, Persona p2) { // TODO Auto-generated method stub return p1.getNombre().compareTo(p2.getNombre()); } }
Creado el comparador el siguiente paso es utilizarlo para ordenar la lista para después imprimirla por consola.
lista.sort(new ComparadorNombre()); lista.forEach(System.out::println);
La lista se imprime ordenada:
Java Comparator y ordenaciones
Hasta aquí todo funciona perfectamente. Sin embargo habrá situaciones en las cuales queramos ordenar por apellido .
Para ello en Java clásico tendríamos que crear otro Comparador.
package com.arquitecturajava.ejemplo1; import java.util.Comparator; public class ComparadorApellido implements Comparator&lt;Persona> { @Override public int compare(Persona p1, Persona p2) { // TODO Auto-generated method stub return p1.getApellido1().compareTo(p2.getApellido1()); } }
Modificamos el código y volvemos a imprimir:
lista.sort(new ComparadorApellido()); lista.forEach(System.out::println);
El resultado es :
Todo funciona , ahora bien si queremos realizar una ordenación por otro campo tenemos que construir un nuevo Comparator . Con lo cual rápidamente nos encontraremos con muchos Comparadores.
Java Comparator en Java 8
Esto en muchos casos es un problema ya que existen muchos tipos de comparaciones y combinaciones posibles. Java 8 solventa este problema utilizando expresiones Lambda.
package com.arquitecturajava.ejemplo1; import java.util.Arrays; import java.util.List; public class Principal { public static void main(String[] args) { // TODO Auto-generated method stub Persona p1= new Persona("pedro","perez","gomez"); Persona p2= new Persona("angel","alvarez","zamora"); Persona p3= new Persona("ana","perez","jimenez"); Persona p4= new Persona("ana","sainz","jimenez"); Persona p5= new Persona("maria","alvarez","alvarez"); List<Persona> lista=Arrays.asList(p1,p2,p3,p4,p5); lista.sort((pa,pb)->pa.getNombre().compareTo(pb.getNombre())); lista.forEach(System.out::println); lista.sort((pa,pb)->pa.getApellido1().compareTo(pb.getApellido1())); lista.forEach(System.out::println); } }
De esta forma se puede conseguir el mismo resultado , pero sin la necesidad de construir clases apoyandonos en Java 8.
No solo eso sino que ademas las expresiones las expresiones lambda a nivel de comparadores permiten su combinación . Por ejemplo imaginémonos que deseamos ordenar la lista primero por apellido1 y luego por apellido2. En Java Clásico no nos quedaría más remedio que implementar una nueva clase Comparator.
Sin embargo en Java 8 podemos encadenar expresiones lamdba a través del método thenComparing del interface Comparator.
Vamos a verlo en código:
package com.arquitecturajava.ejemplo1; import java.util.Arrays; import java.util.Comparator; import java.util.List; public class Principal3 { public static void main(String[] args) { // TODO Auto-generated method stub Persona p1= new Persona("pedro","perez","gomez"); Persona p2= new Persona("angel","alvarez","zamora"); Persona p3= new Persona("ana","perez","jimenez"); Persona p4= new Persona("ana","sainz","jimenez"); Persona p5= new Persona("maria","alvarez","alvarez"); List<Persona>lista=Arrays.asList(p1,p2,p3,p4,p5); Comparator<Persona> comparadorA= (pa,pb)->pa.getApellido1().compareTo(pb.getApellido1()); Comparator<Persona> comparadorB=comparadorA.thenComparing((pa,pb)->pa.getApellido2().compareTo(pb.getApellido2())); lista.sort(comparadorB); lista.forEach(System.out::println); } }
Podemos ver el resultado en la consola:
Nos ha ordenado primero por el apellido1 y luego por el apellido2. Java 8 aporta muchos puntos de mejora sobre java clásico:
Como novato en Java veo
y no sé que es, de donde sale o qué significa. me voy a otro artículo a ver si lo encuentro más comprensible o que explique de donde sale eso
Creo que esta solucionado 🙂