Comparable is een interface die door de klasse van het object zelf wordt geïmplementeerd. Het definieert één methode compareTo(), die de natuurlijke ordelingsvolgorde bepaalt.
Comparator is een aparte interface die de methode compare(o1, o2) implementeert. Hiermee kunnen meerdere manieren van sorteren worden gedefinieerd zonder de code van de klasse zelf te wijzigen.
Wanneer te gebruiken:
Voorbeelden:
// 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); // sorteren op grade Collections.sort(students, byName); // sorteren op name
Is het mogelijk om een List van objecten die geen Comparable implementeren te sorteren zonder Comparator?
Antwoord: Nee. Als de klasse geen Comparable implementeert en er geen Comparator wordt doorgegeven, zal de poging om de collectie te sorteren resulteren in een ClassCastException.
Voorbeeld:
class Animal {} List<Animal> animals = ...; Collections.sort(animals); // ClassCastException, als er geen Comparable is
Verhaal
In een inventarisatieproject vergat ik Comparable te implementeren voor de klasse Item. Er was een poging om te sorteren via Collections.sort(items). Als gevolg hiervan crasht de applicatie regelmatig met ClassCastException vanwege het ontbreken van de compareTo() methode.
Verhaal
In een service voor het berekenen van de scores van studenten had de ontwikkelaar de vergelijking op het veld grade alleen in de methode compareTo() geïmplementeerd. Later was het nodig om te sorteren op naam en geboortedatum, maar de code van de klasse groeide met hulpfuncties, in plaats van verschillende Comparators te gebruiken en complexe logica in compareTo() te vermijden.
Verhaal
In een online bestelsysteem probeerden ze Comparator met een lambda-expressie te gebruiken om bestellingen op datum te sorteren, maar vergaten rekening te houden met de mogelijkheid van null-waarden voor de datum. Het resultaat — onvermoede NullPointerException in productie bij het sorteren van bestellingen zonder leverdatum.