Comparable-grensesnittet
Implementer Comparable for å gi en klasse en naturlig sorteringsrekkefølge, og bruk den med Collections.sort.
Comparable-grensesnittet er en gratis leksjon i Java Academy på CoddyKit. Dette er leksjon 1 av 4. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Java Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Java Academy inneholder totalt 4 leksjoner.
Comparable-grensesnittet
Comparable<T> gir en klasse en naturlig sorteringsrekkefølge. Implementer det for å gjøre instanser sorterbare med Collections.sort(), Arrays.sort() og sorterte samlinger som TreeSet.
Implementere Comparable
Implementer compareTo(T other) slik at metoden returnerer en negativ verdi (this < other), null (like) eller en positiv verdi (this > other).
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)]Kontrakten for compareTo
En korrekt implementering av Comparable må oppfylle en kontrakt:
- Antisymmetri: sgn(a.compareTo(b)) == -sgn(b.compareTo(a))
- Transitivitet: Hvis a > b og b > c, må a > c
- Konsistens: a.compareTo(b) == 0 innebærer at a.equals(b) anbefales på det sterkeste
Trygg sammenligning av primitive typer
Trekk aldri fra primitive verdier i compareTo – heltallsoverflyt kan gi feil resultater. Bruk Integer.compare(), Double.compare() og så videre.
// 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
}Naturlig sorteringsrekkefølge i TreeSet
Klasser som implementerer Comparable, plasseres automatisk i sorterte samlinger som TreeSet og 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 med flere felt
For å sortere etter flere felt kjeder du sammenligninger: først det primære feltet, deretter det sekundære hvis det primære er likt.
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
}
}Konsistens mellom Comparable og equals
Det anbefales på det sterkeste, men er ikke påkrevd, at a.compareTo(b) == 0 hvis og bare hvis a.equals(b). Brudd på dette kan føre til vanskelige feil i sorterte sett og kart.
// 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 elementSortering med Collections.sort
Collections.sort() og Arrays.sort() bruker den naturlige rekkefølgen som er definert av Comparable.
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 i binærsøk
Collections.binarySearch() krever at listen er sortert etter naturlig rekkefølge, og at elementene implementerer Comparable.
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 kontra Comparator
Viktig forskjell:
- Comparable: definerer klassens egen naturlige sorteringsrekkefølge – én per klasse
- Comparator: definerer en ekstern sorteringsrekkefølge – et ubegrenset antall som kan settes sammen
Praktisk: Resultattavle
En resultattavle som bruker Comparable for en naturlig rekkefølge med høyeste poengsum først.
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: 950Kort kontroll
Hva returnerer compareTo() når det gjeldende objektet er mindre enn argumentet?
Oppsummering: Comparable-grensesnittet
Viktig å huske:
- Implementer Comparable<T> for å definere klassens naturlige sorteringsrekkefølge
- compareTo returnerer negativ verdi (mindre), null (lik) eller positiv verdi (større)
- Bruk Integer.compare()/Double.compare() – trekk aldri fra på grunn av risiko for overflyt
- Kjed sammenligninger ved sortering etter flere felt: primær → sekundær
- Naturlig rekkefølge brukes av Collections.sort, Arrays.sort, TreeSet og TreeMap
- Comparable definerer ÉN sorteringsrekkefølge; bruk Comparator for flere rekkefølger
Lær deg Java med en AI-veileder – gratis
Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.
- Kurs
- 104
- Leksjoner
- 374
Ofte stilte spørsmål
Er leksjonen «Comparable-grensesnittet» gratis?
Ja – hele teksten i «Comparable-grensesnittet» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av Java Academy-kurset, kan du oppgradere til CoddyKit PRO. Kurset i Java Academy inneholder totalt 4 leksjoner.
Hva lærer jeg i «Comparable-grensesnittet»?
Implementer Comparable for å gi en klasse en naturlig sorteringsrekkefølge, og bruk den med Collections.sort. Du øver på Java Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.
Trenger jeg erfaring for å begynne med Java Academy?
Ingen tidligere erfaring er nødvendig. Java Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 1 av 4.
Hvor lang tid tar leksjonen «Comparable-grensesnittet»?
De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.
Kan jeg skrive og kjøre kode i denne Java Academy-leksjonen?
Ja. Alle Java Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.
Alle leksjonene i dette kurset
- Comparable-grensesnittet
- Comparator og sortering med lambda
- Sortering på flere nøkler med thenComparing
- Sortering av tabeller og samlinger i praksis