Comparable es una interfaz que es implementada por la propia clase del objeto. Define un método compareTo(), que establece el orden natural de clasificación.
Comparator es una interfaz separada que implementa el método compare(o1, o2). Permite definir múltiples formas de ordenación sin modificar el código de la propia clase.
Cuándo usar:
Ejemplos:
// Comparable class Student implements Comparable<Student> { String name; int grade; public int compareTo(Student other) { return this.grade - other.grade; } } // Comparator Comparator<Student> byName = new Comparator<Student>() { public int compare(Student s1, Student s2) { return s1.name.compareTo(s2.name); } }; List<Student> students = ...; Collections.sort(students); // ordenación por grade Collections.sort(students, byName); // ordenación por name
¿Se puede ordenar una lista de objetos que no implementan Comparable sin un Comparator?
Respuesta: No. Si la clase no implementa Comparable y no se pasa explícitamente un Comparator, intentar ordenar la colección resultará en una ClassCastException.
Ejemplo:
class Animal {} List<Animal> animals = ...; Collections.sort(animals); // ClassCastException, si no hay Comparable
Historia
En el proyecto de inventario olvidé implementar Comparable para la clase Item. Se intentó ordenar a través de Collections.sort(items). Como resultado, la aplicación se caía regularmente con ClassCastException debido a la falta del método compareTo().
Historia
En el servicio de cálculo de calificaciones de los estudiantes, el desarrollador implementó la comparación por el campo grade solo en el método compareTo(). Más tarde, se necesitó ordenar por nombre y fecha de nacimiento, pero el código de la clase se hizo voluminoso con métodos auxiliares, en lugar de usar diferentes Comparator y evitar la lógica compleja en compareTo().
Historia
En el producto de pedidos en línea, intentamos usar Comparator con una expresión lambda para ordenar pedidos por fecha, pero olvidamos considerar la posibilidad de valores null para la fecha. El resultado — inesperados NullPointerException en producción al ordenar pedidos sin fecha de entrega.