Comparable 是「内比较器」:类实现 compareTo 定义自身的自然排序,一个类只有一种,被 Collections.sort()、TreeSet/TreeMap 默认使用。Comparator 是「外比较器」:独立的比较策略,可定义多个(按姓名、按年龄……),调用时显式传入,优先级高于自然排序。选择依据:排序规则是对象固有属性就实现 Comparable;规则随场景变化或类不可修改(第三方类)就用 Comparator。
现代写法:Java 8 起 Comparator 提供丰富工厂方法——Comparator.comparing(Person::getAge).thenComparing(Person::getName).reversed(),链式组合取代手写匿名类。两个易错点:1)compareTo 的返回差值不要用 a − b 减法(整数溢出,用 Integer.compare);2)与 equals 的一致性——TreeSet/TreeMap 用 compareTo 判等而非 equals,若二者不一致(compareTo 返回 0 但 equals 为 false)会出现「元素存进去了却 contains 不到」的诡异行为,BigDecimal 的 compareTo(忽略标度)与 equals 就是经典案例。追问方向:Comparator.comparing 遇到 null 字段怎么办(nullsFirst/nullsLast)、TimSort 对比较器非对称违规的检测(IncompatibleClassChangeError 类报错)。
(约 420 字)