Cómo ordenar un array en Java utilizando Comparable y Comparator

Ejemplo de uso de las interfaces Comparable y Comparator Java para ordenar un array de objetos 

En esta entrada vamos a explicar como se puede ordenar un array de objetos en Java mediante el uso de la interface Comparable. Vamos a crear un array de tipo Empleado y posteriormente lo ordenaremos por nombre de empleado y lo mostraremos ordenado. Continuaremos el ejemplo ordenando de nuevo el array esta vez por el campo sueldo. Para hacer esta ordenación se utilizará la interface Comparator.
Disponemos de la clase Empleado que contiene los siguientes atributos:
public class Empleado{
    private String nif;
    private String nombre;
    private double sueldo;
  
    ///Resto de métodos de la case
}
Esta clase la vamos a utilizar en un programa que pide los datos de los empleados y los guarda en un array de 20 elementos llamado empleados que se encuentra en la clase principal. Posteriormente los mostrará ordenados por nombre.
public class EjemploComparableComparator {
    static Empleado[] empleados = new Empleado[20];
    static int indice = 0;
    static Scanner sc = new Scanner(System.in);

    public static void main(String[] args)  {
        leerEmpleados(); //en este método se llena el array empleados
        Arrays.sort(empleados); //ordena los empleados por nombre
        mostrarEmpleados(); //muestra el array empleados
    }
}

Para ordenar hemos utilizado:

Arrays.sort(empleados);

Para que el método sort sepa que para ordenar el array tiene que comparar los nombres de los empleados, debemos indicárselo de alguna forma. La forma de indicarle a sort el criterio de ordenación es la siguiente:
1. La Clase Empleado debe implementar la interface Comparable:
public class Empleado implements Comparable<Empleado> {

2. Nos aparecerá un error:


Que solucionamos pulsando en la opción Implement all abstract methods: 


3. Comprobamos que al final de la clase se ha creado un nuevo método llamado compareTo

4. Eliminamos la línea throw new….. y en su lugar escribimos el código para comparar los nombres de empleados:
El método compareTo debe devolver 0 si son iguales, <0 si el de la izquierda (this) es menor que el de la derecha (t) ó >0 si el de la izquierda es mayor que el de la derecha.
En este caso como se trata de 2 String los podemos comparar con el método compareToIgnoreCase de String y devolver el resultado que obtengamos.
De esta forma cuando invoquemos al método sort en la instrucción  Arrays.sort(empleados) se utilizará el método compareTo que acabamos de escribir para decidir el orden de los objetos. Este proceso es transparente para nosotros. El método sort aplicado a un array de objetos utiliza un algoritmo de ordenación mergesort. Va comparando los elementos del array según este algoritmo y decide si dos elementos están desordenados según el código que hemos escrito en el método compareTo.
Supongamos ahora que además de mostrar el array ordenado por nombre también queremos mostrarlo ordenado por sueldo. Para eso tendremos que utilizar la interface Comparator de la siguiente forma:
1. Creamos una clase nueva. La podemos llamar por ejemplo OrdenSueldo. Esta clase debe implementar la interface Comparator.
public class OrdenSueldo implements Comparator<Empleado>{
2. Nos indica que no tenemos el import. Lo añadimos:


3. A continuación nos indica otro error similar al que vimos en el ejemplo anterior

4. Lo solucionamos pulsando en Implement all abstract methods:

5. Esto crea el método compare:

6. Eliminamos la línea throw new….. y en su lugar escribimos el código para comparar los sueldos.


El método compare debe devolver 0 si son iguales, <0 si el de la izquierda (o1) es menor que el de la derecha (o2) ó >0 si el de la izquierda es mayor que el de la derecha.
Para ordenar el array de empleados por sueldo debemos escribir ahora:
Arrays.sort(empleados, new OrdenSueldo());
Para utilizar el Comparator se crea un objeto de la clase que hemos creado. Este objeto se utiliza como parámetro cuando se invoca al método sort. En este caso sort utilizará como criterio de ordenación el método compare que hemos escrito en la clase OrdenSueldo.

Otra forma de hacer esto, sin tener que crear una nueva clase cada vez que queramos ordenar por un criterio distinto es escribir el código completo del comparator cuando se hace la llamada al método sort:
De esta forma nos evitamos añadir clases innecesarias al proyecto. Debemos tener en cuenta que podemos ordenar los objetos de un array por muchos criterios distintos y para cada uno habría que crear una clase nueva que implemente la interface Comparator con su método compare correspondiente.

1 comentario: