De Comparable-interface
Implementeer Comparable om een klasse een natuurlijke ordening te geven en gebruik deze met Collections.sort.
De Comparable-interface is een gratis Java Academy-les op CoddyKit. Dit is les 1 van 4. Je kunt de volledige les hieronder gratis lezen en daarna in de browser praktisch oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject Java Academy. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus Java Academy bevat in totaal 4 lessen.
De Comparable-interface
Comparable<T> geeft een class een natuurlijke ordening. Implementeer deze om instanties sorteerbaar te maken met Collections.sort(), Arrays.sort() en gesorteerde collecties zoals TreeSet.
Comparable implementeren
Implementeer compareTo(T other) met een negatieve waarde (dit < other), nul (gelijk) of een positieve waarde (dit > other) als resultaat.
class Product implements Comparable<Product> {
private final String name;
private final double price;
Product(String name, double price) {
this.name = name; this.price = price;
}
@Override
public int compareTo(Product other) {
return Double.compare(this.price, other.price); // ascending by price
}
@Override public String toString() { return name + "($" + price + ")"; }
}
List<Product> products = new ArrayList<>(List.of(
new Product("Mouse", 29.99),
new Product("Laptop", 999.0),
new Product("Keyboard", 79.99)
));
Collections.sort(products);
System.out.println(products); // [Mouse($29.99), Keyboard($79.99), Laptop($999.0)]Het contract van compareTo
Comparable correct implementeren vereist dat je aan een contract voldoet:
- Antisymmetrie: sgn(a.compareTo(b)) == -sgn(b.compareTo(a))
- Transitiviteit: als a > b en b > c, dan a > c
- Consistentie: a.compareTo(b) == 0 impliceert a.equals(b); dit wordt sterk aanbevolen
Primitieve waarden veilig vergelijken
Trek nooit primitieve waarden van elkaar af in compareTo — een integer-overflow kan onjuiste resultaten opleveren. Gebruik Integer.compare(), Double.compare() enzovoort.
// WRONG: integer subtraction can overflow
int compareTo(Player other) {
return this.score - other.score; // overflow if scores differ by > Integer.MAX_VALUE
}
// CORRECT: use Integer.compare
int compareTo(Player other) {
return Integer.compare(this.score, other.score);
}
// For strings: delegate to String.compareTo
int compareTo(Player other) {
return this.name.compareTo(other.name); // String handles it correctly
}Natuurlijke ordening in TreeSet
Classes die Comparable implementeren, worden automatisch geplaatst in gesorteerde collecties zoals TreeSet en TreeMap.
class Priority implements Comparable<Priority> {
enum Level { LOW, MEDIUM, HIGH, CRITICAL }
final Level level;
final String task;
Priority(Level level, String task) { this.level = level; this.task = task; }
@Override
public int compareTo(Priority other) {
return this.level.compareTo(other.level); // enum ordinal order
}
@Override public String toString() { return level + ": " + task; }
}
TreeSet<Priority> queue = new TreeSet<>();
queue.add(new Priority(Priority.Level.CRITICAL, "Fix prod crash"));
queue.add(new Priority(Priority.Level.LOW, "Update docs"));
queue.add(new Priority(Priority.Level.HIGH, "Deploy feature"));
queue.forEach(System.out::println);
// LOW: Update docs
// HIGH: Deploy feature
// CRITICAL: Fix prod crashComparable met meerdere velden
Als je op meerdere velden wilt sorteren, keten je vergelijkingen: eerst het primaire veld en daarna het secundaire veld als het primaire veld gelijk is.
class Employee implements Comparable<Employee> {
final String dept, name;
final double salary;
Employee(String dept, String name, double salary) {
this.dept = dept; this.name = name; this.salary = salary;
}
@Override
public int compareTo(Employee other) {
int deptCmp = this.dept.compareTo(other.dept);
if (deptCmp != 0) return deptCmp; // primary: by dept
return this.name.compareTo(other.name); // secondary: by name
}
}Consistentie tussen Comparable en equals
Het wordt sterk aanbevolen (maar is niet vereist) dat a.compareTo(b) == 0 dan en slechts dan als a.equals(b). Als je dit schendt, ontstaan subtiele fouten in gesorteerde sets en maps.
// BigDecimal violates this: new BigDecimal("2.0").compareTo(new BigDecimal("2.00")) == 0
// but new BigDecimal("2.0").equals(new BigDecimal("2.00")) == false
// This causes TreeSet to treat them as equal (only one stored)
TreeSet<java.math.BigDecimal> set = new TreeSet<>();
set.add(new java.math.BigDecimal("2.0"));
set.add(new java.math.BigDecimal("2.00"));
System.out.println(set.size()); // 1 — compareTo-equal → same elementSorteren met Collections.sort
Collections.sort() en Arrays.sort() gebruiken de natuurlijke volgorde die door Comparable wordt bepaald.
List<String> names = new ArrayList<>(List.of("Charlie", "Alice", "Bob"));
Collections.sort(names); // natural alphabetical order
System.out.println(names); // [Alice, Bob, Charlie]
String[] arr = {"banana", "apple", "cherry"};
Arrays.sort(arr);
System.out.println(Arrays.toString(arr)); // [apple, banana, cherry]
// Stream sorted() uses natural order
names.stream().sorted().forEach(System.out::println);Comparable bij binair zoeken
Collections.binarySearch() vereist dat de lijst volgens de natuurlijke volgorde is gesorteerd en dat de elementen Comparable implementeren.
List<Integer> sorted = new ArrayList<>(List.of(1, 3, 5, 7, 9, 11));
int idx = Collections.binarySearch(sorted, 7);
System.out.println("Found 7 at index: " + idx); // 3
int missing = Collections.binarySearch(sorted, 4);
System.out.println("4 not found, insertion point: " + (-missing - 1)); // 2Comparable versus Comparator
Belangrijk onderscheid:
- Comparable: definieert de eigen natuurlijke ordening van een class — één per class
- Comparator: definieert een externe ordening — onbeperkt en combineerbaar
Praktisch: klassement
Een klassement dat Comparable gebruikt voor een natuurlijke volgorde met aflopende scores.
class LeaderboardEntry implements Comparable<LeaderboardEntry> {
final String player;
final int score;
final long timestamp;
LeaderboardEntry(String player, int score) {
this.player = player; this.score = score;
this.timestamp = System.nanoTime();
}
@Override
public int compareTo(LeaderboardEntry other) {
int scoreCmp = Integer.compare(other.score, this.score); // descending
if (scoreCmp != 0) return scoreCmp;
return Long.compare(this.timestamp, other.timestamp); // earlier = higher
}
@Override public String toString() { return player + ": " + score; }
}
TreeSet<LeaderboardEntry> board = new TreeSet<>();
board.add(new LeaderboardEntry("Alice", 950));
board.add(new LeaderboardEntry("Bob", 1200));
board.add(new LeaderboardEntry("Carol", 950));
board.forEach(System.out::println);
// Bob: 1200 / Alice: 950 / Carol: 950Korte controle
Wat geeft compareTo() terug wanneer het huidige object kleiner is dan het argument?
Samenvatting: de Comparable-interface
Belangrijkste punten:
- Implementeer Comparable<T> om de natuurlijke ordening van een class te definiëren
- compareTo geeft negatief (kleiner), nul (gelijk) of positief (groter) terug
- Gebruik Integer.compare()/Double.compare() — trek nooit waarden van elkaar af (risico op overflow)
- Keten vergelijkingen voor sorteren op meerdere velden: primair → secundair
- De natuurlijke volgorde wordt gebruikt door Collections.sort, Arrays.sort, TreeSet en TreeMap
- Comparable definieert ÉÉN volgorde; gebruik Comparator voor meerdere ordeningen
Leer Java met een AI-tutor — gratis
Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.
- Cursussen
- 104
- Lessen
- 374
Veelgestelde vragen
Is de les “De Comparable-interface” gratis?
Ja — de volledige tekst van “De Comparable-interface” kun je hier gratis op het web lezen. Als je interactief wilt oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is, en de rest van de cursus Java Academy wilt ontgrendelen, kun je upgraden naar CoddyKit PRO. De cursus Java Academy bevat in totaal 4 lessen.
Wat leer ik in “De Comparable-interface”?
Implementeer Comparable om een klasse een natuurlijke ordening te geven en gebruik deze met Collections.sort. Je oefent met Java Academy door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.
Heb ik ervaring nodig om met Java Academy te beginnen?
Ervaring vooraf is niet nodig. Java Academy op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 1 van 4.
Hoe lang duurt de les “De Comparable-interface”?
De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.
Kan ik code schrijven en uitvoeren in deze les over Java Academy?
Ja. Elke les over Java Academy bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.
Alle lessen in deze cursus
- De Comparable-interface
- Comparator en sorteren met lambda-expressies
- Sorteren op meerdere sleutels met thenComparing
- Arrays en collecties sorteren in de praktijk