ทั้งคู่กำหนดวิธีจัดลำดับวัตถุ แต่ต่างกัน: Comparable กำหนดการจัดลำดับธรรมชาติของคลาส (ใช้งานโดยคลาสเอง) ในขณะที่ Comparator กำหนดการจัดลำดับภายนอกทางเลือก (วัตถุที่แยกต่างหาก) ทางเลือกขึ้นอยู่กับว่าการจัดลำดับเป็นสิ่งที่สำคัญหรือสถานการณ์
ทั้งคู่กำหนดวิธีจัดลำดับวัตถุ แต่ต่างกัน: Comparable กำหนดการจัดลำดับธรรมชาติของคลาส (ใช้งานโดยคลาสเอง) ในขณะที่ Comparator กำหนดการจัดลำดับภายนอกทางเลือก (วัตถุที่แยกต่างหาก) ทางเลือกขึ้นอยู่กับว่าการจัดลำดับเป็นสิ่งที่สำคัญหรือสถานการณ์
public class Person implements Comparable<Person> {
private String name;
private int age;
@Override
public int compareTo(Person other) { // defines THE natural order
return Integer.compare(this.age, other.age); // by age
}
// return: negative if this < other, 0 if equal, positive if this > other
}
List<Person> people = ...;
Collections.sort(people); // uses compareTo — sorts by age (the natural order)
Comparable อยู่ข้างในคลาสผ่าน compareTo() ซึ่งกำหนดการจัดลำดับเริ่มต้นเพียงหนึ่งเดียว ใช้โดยอัตโนมัติโดย Collections.sort, TreeSet, TreeMap เป็นต้น
// define orderings OUTSIDE the class — as many as you need
Comparator<Person> byName = (a, b) -> a.getName().compareTo(b.getName());
Comparator<Person> byAge = Comparator.comparingInt(Person::getAge);
people.sort(byName); // sort by name
people.sort(byAge.reversed()); // by age, descending
Comparator คือวัตถุแยกต่างหาก ที่ให้คุณกำหนดการจัดลำดับที่แตกต่างกันหลายแบบสำหรับคลาสเดียวกันโดยไม่ต้องแก้ไข
Comparator<Person> comp = Comparator
.comparing(Person::getLastName) // primary: last name
.thenComparing(Person::getFirstName) // tie-break: first name
.thenComparingInt(Person::getAge) // then: age
.reversed(); // reverse the whole thing
people.sort(comp);
เมธอด comparing/thenComparing ในรูปแบบตัวสร้างทำให้การเรียงลำดับหลายฟิลด์ที่ซับซ้อนกระชับและอ่านง่าย
Comparable → the class has ONE obvious natural order (numbers by value, strings
alphabetically, dates chronologically); you own the class
Comparator → you need MULTIPLE orderings, situational/custom ordering, OR you
can't modify the class (e.g. sorting a third-party type differently)
การจัดลำดับวัตถุเป็นความต้องการอย่างต่อเนื่อง — การเรียงลำดับรายการ ใช้ TreeSet/TreeMap ค้นหา min/max
การเข้าใจความแตกต่างระหว่าง Comparable-vs-Comparator ช่วยให้คุณเลือกได้อย่างถูกต้อง: Comparable สำหรับการจัดลำดับที่สำคัญเพียงอย่างเดียวของคลาส (สร้างเข้า ใช้โดยค่าเริ่มต้น), Comparator เพื่อความยืดหยุ่นของการจัดลำดับหลายตัวหรือภายนอก (เรียงลำดับข้อมูลเดียวกันตามฟิลด์ต่างๆ หรือจัดลำดับประเภทที่คุณไม่ควบคุม)
API Comparator ที่ทันสมัยและคล่องตัว (comparing/thenComparing/reversed) ทำให้การเรียงลำดับหลายระดับมีความสวยงาม
การเรียนรู้ทั้งสองอย่าง — และเมื่อแต่ละอย่างเหมาะสม — จำเป็นสำหรับการทำงานกับโครงสร้างข้อมูลที่เรียงลำดับ และเป็นหัวข้อการปฏิบัติและการสัมภาษณ์ที่บ่อยครั้งใน Java