Comparable — est une interface qui est implémentée par la classe de l'objet elle-même. Elle définit une méthode compareTo(), qui détermine l'ordre naturel de tri.
Comparator — est une interface distincte, qui implémente la méthode compare(o1, o2). Elle permet de définir plusieurs façons de trier sans modifier le code de la classe elle-même.
Quand utiliser :
Exemples :
// 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); // tri par grade Collections.sort(students, byName); // tri par name
Peut-on trier une liste d'objets ne réalisant pas Comparable, sans Comparator ?
Réponse : Non. Si la classe ne réalise pas Comparable et qu'aucun Comparator n'est explicitement fourni, la tentative de trier la collection entraînera une ClassCastException.
Exemple :
class Animal {} List<Animal> animals = ...; Collections.sort(animals); // ClassCastException, si pas de Comparable
Histoire
Dans le projet d'inventaire, j'ai oublié d'implémenter Comparable pour la classe Item. Une tentative de tri via Collections.sort(items) a entraîné des plantages réguliers de l'application avec ClassCastException en raison de l'absence de la méthode compareTo().
Histoire
Dans le service de calcul des classements des étudiants, le développeur a implémenté la comparaison par le champ grade uniquement dans la méthode compareTo(). Plus tard, il a fallu trier par nom et par date de naissance, mais le code de la classe s'est alourdi avec des méthodes auxiliaires, au lieu d'utiliser différents Comparator et d'éviter une logique complexe dans compareTo().
Histoire
Dans le produit de commande en ligne, ils ont tenté d'utiliser Comparator avec une expression lambda pour trier les commandes par date, mais ont oublié de prendre en compte la possibilité des valeurs null pour la date. Résultat — des NullPointerException inattendues en production lors du tri des commandes sans date de livraison.