Comparable 是一个由对象的类自己实现的接口。定义了一个方法 compareTo(),用于定义自然排序顺序。
Comparator 是一个单独的接口,实现了方法 compare(o1, o2)。它允许在不更改类自身代码的情况下定义多种排序方式。
何时使用:
示例:
// 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); // 按grade排序 Collections.sort(students, byName); // 按name排序
可以不实现Comparable而使用Comparator来排序对象的List吗?
回答: 不能。如果类没有实现Comparable且没有明确传入Comparator,则尝试对集合进行排序将引发ClassCastException。
示例:
class Animal {} List<Animal> animals = ...; Collections.sort(animals); // ClassCastException,如果没有Comparable
故事
在库存项目中,忘记为类Item实现Comparable。尝试通过Collections.sort(items)进行排序,结果导致应用程序因缺少compareTo()方法而频繁崩溃ClassCastException。
故事
在学生评分计算服务中,开发者仅在compareTo()方法中实现了基于grade的比较,后来需要按姓名和出生日期排序,导致类代码因辅助方法而膨胀,而没有使用不同的Comparator,避免在compareTo()中复杂的逻辑。
故事
在在线订购产品中,尝试使用Comparator和Lambda表达式按日期对订单进行排序,但忘记考虑日期的null值情况。结果——在生产环境中排序没有交货日期的订单时出现意外的NullPointerException。