Java:compareTo

compareTo 是 Java 里用来比较两个对象大小或顺序的方法,属于 Comparable 接口,返回值是整数:负数表示当前对象小,0 表示相等,正数表示当前对象大。

Java 里很多常用类已经实现了这个方法

  1. 字符串 String:按字典顺序比,也就是逐个字符比 Unicode 编码值 。
  • 如果第一个字符不一样,直接返回这两个字符编码的差值。

  • 如果前面字符都一样,但长度不一样,返回长度的差值 。

  • 比如"abc"比"abd"小,返回负数;"abc"比"abc"相等,返回 0。

  1. 数字包装类:像 Integer、Long、Double 这些都能比,比的是数值大小 。
  • 注意基本数据类型 int 不能直接用,得转成 Integer 包装类。

  • 比如 Integer 的 5 比 3,返回正数(1);5 比 5,返回 0。

  1. 其他类:BigDecimal、Date、File 等也支持 。
  • File 类比的是文件路径名的字典顺序,不同操作系统下可能因为大小写敏感不一样而有差异 。

如果想让自己写的类也能排序,比如按年龄、按价格排,就得让类实现 Comparable 接口,并重写 compareTo 方法 。

  1. 基本步骤:
  • 在类声明后面加上 implements Comparable<类名>。

  • 覆盖 compareTo 方法,在里面写比较逻辑 。

  1. 比较逻辑:
  • 通常先比较主要字段,如果不相等直接返回结果。

  • 如果主要字段相等,再比较次要字段 。

  • 比如 Person 类,可以先比较年龄,年龄一样再比较姓名 。

  1. 调用:
  • 实现好后,就可以把对象放进列表,用 Collections.sort 或 Arrays.sort 直接排序 。

  • 也能用在 TreeSet、TreeMap 里当键,会自动保持有序 。

这个方法虽然好用,但有几个坑容易踩。

  1. 不能传空值:参数不能是 null,否则会报 NullPointerException 错误 。
  • 建议在调用前先判断一下是不是空,或者在业务层处理好空值。
  1. 防止数字溢出:
  • 如果用两个 int 相减来返回结果(比如 this.age - other.age),数字太大或太小可能会溢出,导致正负号变反 。

  • 推荐用 Integer.compare(this.age, other.age) 这种工具方法,安全又方便 。

  1. 和 Comparator 的区别:
  • compareTo 是类内部定好的"自然顺序",一个类只能有一种 。

  • Comparator 是外部临时定的"定制顺序",可以有很多种,比如按价格排完再按销量排 。

  • 如果一个类既有 compareTo 又用了 Comparator 排序,优先按 Comparator 的逻辑来 。

  1. 和 equals 保持一致:
  • 如果 compareTo 返回 0 说两个对象相等,那 equals 方法最好也返回 true,不然在 TreeSet 里可能会丢数据 。