Double/Float--该类显式地提供了排序规则,并为正零和负零,以及NaN都提供了相等性检查,以确保它的compareTo()方法符合“一致性相等”。

  CharSet--该类基于ID或名称。equals()方法对待字段串是大小写敏感的,但compareTo()方法却不这样。虽然名称一般会符合某种标准,但这是一种值得怀疑的“一致性”。

  *Buffer(nio)--该簇类的比较基于缓冲存放的内容,在我的测试中equals()和compareTo()是“一致的”。

  Rdn(ldap)--该类的比较基于状态的标准化格式,因此也是“一致性相等”。

  ObjectStreamField(序列化)--该类的比较基于名称,但会首先对基本数据类型进行排序。因为没有覆盖equals()方法,所以是“非一致性相等”。

  ...

  注意:对于大多数的例子,我都不得不查看其源代码或编写测试程序以确定该类是不是符合“一致性相等”。这儿有一个不错地清理Javadoc和检验UUID equals()方法的Adopt-a-JDK任务。

  JSR-310

  一直看到许多关于BigDecimal的问题,已有计划将JSR-310中的类改造成“一致性相等”,近的一些帖子显示这将造成多么大的争议。

  基本上,为某些类定义equals()和compareTo()看起来很容易。LocalDate表示某单一日历系统中的某个日期,所以它有一个显而易见的排序算法和相等规则。LocalTime则表示某个时刻,所以它也有一个明显的排序算法和相等规则。Instant表示时间线上的某个时刻,那么它的排序与相等也是显见的。

  但在其它的情况下,这不是那么显而易见了。考虑这样一个类OffsetDateTime:

    dt1 = OffsetDateTime.parse("2012-11-05T06:00+01:00"); 
    dt2 = OffsetDateTime.parse("2012-11-05T07:00+02:00");

  这样的两个日期-时刻对象代表时间线上一个相同的时刻点,但它们有不同的本地时,而且相对的UTC/格林威治时间的偏移量也不相同。

  那么有一个问题要留给读者们...你更倾向于如下哪种观点...

  1、dt1不等于dt2,compareTo()分别比较本地时与偏移量,使用“一致性相等”(使用独立的Comparator基于时刻对其进行排序)。

  2、dt1不等于dt2,compareTo()基于时间线的上时刻点,使用“非一致性相等”。

  3、dt1等于dt2,compareTo()基于时间线的上时刻点,使用“一致性相等”。

  4、dt1等于dt2,且不实现Comparable接口。

  5、dt1不等于dt2,且不实现Comparable接口。

  我个人更倾向于让dt1.equals(dt2)返回true这种方案,但我仍持开放态度。

  顺便地,也可以将这个问题提给BigDecimal,如果你能修改这个类,使其符合“一致性相等”,你会修改它的equals()方法,还是compareTo()方法?