Comparable y Comparator

Numerosas operaciones con colecciones exigen que sus elementos sean comparables, es decir, que se pueda determinar que un elemento es menor, igual o mayor que otro. Esta propiedad se establece a nivel de clase, implementando la interfaz Comparable, o bien la interfaz Comparator. 

Comparable

La interfaz Comparable se utiliza para establecer un orden natural entre los objetos de una misma clase. La declaración de la interfaz es la siguiente (paquete java.lang):

       public interface Comparable{
                  public int compareTo(Object ob);
       }

Si compareTo() devuelve un negativo significa que el objeto que llama al método es menor que el pasado en el argumento; si devuelve o significa que son iguales, y si devuelve un positivo el objeto que llama al método es mayor que el pasado en el argumento. La clase Racional del post de Arrays y Collections implementa la interfaz Comparable, el programador de la clase ha fijado la forma de comparar números racionales.

Nota

Todas las clases que representan a tipos primitivos (wraper): Integer, Double, . . ., y la clase String implementan la interfaz Comparable. La implementación de compareTo() en String distingue mayúsculas de minúsculas.

Comparator

Hay métodos de ordenación y búsqueda de objetos que utilizan la interfaz Comparator para determinar el orden natural entre dos elementos. Esta interfaz se encuentra en el paquete java.util. Su declaración es la siguiente:

       public interface Comparator{
                  public int compare(Object ob1, Object ob2);
                  public boolean equals(Object ob);
       }

El método compare() relaciona dos objetos, no necesariamente del mismo tipo. Devolverá un negativo si el objeto ob1 es menor que el segundo objeto, cero si son iguales y positivo si ob1 es mayor que ob2. El comportamiento de compare() tiene que ser compatible con el resultado del método equals(), es decir, si este devuelve true, compare() tendrá que devolver 0.

Ejemplo

       public class Cuadro{

               int largo;
               int ancho;
               . . .
       }

       class Compara implements Comparator{

               public int compare(){
                          Cuadro c1 = (Cuadro)ob1;
                          Cuadro c2 = (Cuadro)ob2;
                          if(c1.largo == c2.largo && c1.ancho == c2.ancho)
                                     return 0;
                          else
                                     // c1 es menor que c2 si, en superficie, c1 es menor
                                     return (c1.largo*c1.ancho) – (c2.largo*c2.ancho);
               }
       }

Nota

Los métodos que utilizan un argumento de tipo Comparator se llaman pasando una referencia a la clase que implementa la interfaz Comparator. Por ejemplo:

       class Alba implements Comparator{. . .}
       Collections.sort(lista, new Alba());