Antara Muka Comparable
Laksanakan Comparable untuk memberikan kelas susunan semula jadi dan gunakannya dengan Collections.sort.
Antara Muka Comparable ialah pelajaran Java Academy percuma di CoddyKit. Ini ialah pelajaran 1 daripada 4. Anda boleh membaca keseluruhan pelajaran di bawah secara percuma — kemudian berlatih secara praktikal dalam pelayar menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Java Academy, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Java Academy merangkumi sejumlah 4 pelajaran.
Antara Muka Comparable
Comparable<T> memberikan sesebuah class susunan semula jadi. Laksanakan antara muka ini supaya tika class boleh diisih dengan Collections.sort(), Arrays.sort() dan koleksi terisih seperti TreeSet.
Melaksanakan Comparable
Laksanakan compareTo(T other) supaya mengembalikan nilai negatif (this < other), sifar (sama) atau positif (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)]Kontrak compareTo
Pelaksanaan Comparable yang betul memerlukan pematuhan terhadap kontrak:
- Antisimetri: sgn(a.compareTo(b)) == -sgn(b.compareTo(a))
- Transitiviti: jika a > b dan b > c, maka a > c
- Ketekalan: a.compareTo(b) == 0 bermaksud a.equals(b); pematuhan ini sangat disyorkan
Membandingkan Primitif dengan Selamat
Jangan sekali-kali menolak nilai primitif dalam compareTo — limpahan integer boleh menghasilkan keputusan yang salah. Gunakan Integer.compare(), Double.compare() dan sebagainya.
// 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
}Susunan Semula Jadi dalam TreeSet
Class yang melaksanakan Comparable ditempatkan secara automatik dalam koleksi terisih seperti TreeSet dan 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 Berbilang Medan
Untuk mengisih berdasarkan berbilang medan, rangkaikan perbandingan: medan utama, kemudian medan sekunder jika medan utama sama.
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
}
}Ketekalan Comparable dan equals
Sangat disyorkan (tetapi tidak diwajibkan) agar a.compareTo(b) == 0 jika dan hanya jika a.equals(b). Pelanggaran ini menyebabkan pepijat yang sukar dikesan dalam set dan peta terisih.
// 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 elementPengisihan dengan Collections.sort
Collections.sort() dan Arrays.sort() menggunakan susunan semula jadi yang ditakrifkan oleh 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 dalam Carian Binari
Collections.binarySearch() memerlukan senarai diisih mengikut susunan semula jadi dan elemennya melaksanakan 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 berbanding Comparator
Perbezaan utama:
- Comparable: mentakrifkan susunan semula jadi class itu sendiri — satu bagi setiap class
- Comparator: mentakrifkan susunan luaran — tidak terhad dan boleh digabungkan
Amali: Papan Pendahulu
Papan pendahulu yang menggunakan Comparable untuk susunan semula jadi berdasarkan skor menurun.
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: 950Semakan Pantas
Apakah nilai yang dikembalikan oleh compareTo() apabila objek semasa lebih kecil daripada argumen?
Imbas Kembali: Antara Muka Comparable
Perkara penting:
- Laksanakan Comparable
untuk mentakrifkan susunan semula jadi sesebuah class - compareTo mengembalikan nilai negatif (lebih kecil), sifar (sama) atau positif (lebih besar)
- Gunakan Integer.compare()/Double.compare() — jangan sekali-kali melakukan penolakan kerana risiko limpahan
- Rangkaikan perbandingan untuk pengisihan berbilang medan: utama → sekunder
- Susunan semula jadi digunakan oleh Collections.sort, Arrays.sort, TreeSet dan TreeMap
- Comparable mentakrifkan SATU susunan; gunakan Comparator untuk berbilang susunan
Pelajari Java dengan tutor kecerdasan buatan — percuma
Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.
- Kursus
- 104
- Pelajaran
- 374
Soalan Lazim
Adakah pelajaran “Antara Muka Comparable” percuma?
Ya — teks penuh “Antara Muka Comparable” boleh dibaca secara percuma di web ini. Untuk berlatih secara interaktif menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7, serta membuka kunci baki kursus Java Academy, tingkat taraf kepada CoddyKit PRO. Kursus Java Academy merangkumi sejumlah 4 pelajaran.
Apakah yang akan saya pelajari dalam “Antara Muka Comparable”?
Laksanakan Comparable untuk memberikan kelas susunan semula jadi dan gunakannya dengan Collections.sort. Anda berlatih Java Academy menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.
Adakah saya memerlukan pengalaman untuk memulakan Java Academy?
Tiada pengalaman terdahulu diperlukan. Pembelajaran Java Academy di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 1 daripada 4.
Berapa lamakah pelajaran “Antara Muka Comparable” diambil?
Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.
Bolehkah saya menulis dan menjalankan kod dalam pelajaran Java Academy ini?
Ya. Setiap pelajaran Java Academy menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.
Semua pelajaran dalam kursus ini
- Antara Muka Comparable
- Comparator dan Pengisihan Lambda
- Pengisihan Berbilang Kunci dengan thenComparing
- Pengisihan Tatasusunan dan Koleksi dalam Amalan