为什么可比较的自然排序需要与equals方法一致?

时间:2013-08-18 18:18:19

标签: java generics collections

度假后回来:)带问题。我正在阅读Comparable接口文档 ComparableDocumentation。我明白,我们使用可比较的,因为它将为我们提供排序和自然排序。在文档中,它写成。

  

强烈建议(尽管不要求)自然   排序与平等一致。这是因为排序集   没有明确的比较器的(和有序的地图)表现得很奇怪"奇怪的是#34;什么时候   它们与自然顺序的元素(或键)一起使用   与equals不一致。特别是,这样的排序集(或排序的   map)违反了定义的集合(或映射)的一般合同   就平等方法而言。

Comparable如何与equals相关。 Comparable有compareTo方法和为什么它需要与equals方法一致?我无法理解这个概念。

同样引用消息来源,有人也可以详细说明这一点

  

例如,如果添加两个键a和b使得(!a.equals(b)&&   a.compareTo(b)== 0)到不使用显式的有序集   比较器,第二个add操作返回false(和大小   排序集不会增加)因为a和b是等价的   排序集的观点。

感谢。

3 个答案:

答案 0 :(得分:8)

compareTo返回0的语义是两个对象,相等。在另一种方法中对同一关系的另一个定义显然会导致许多类型的问题,如您的引文中所述:SortedSet实现中的典型算法依赖于compareTo,但是总契约Set接口指定它不能包含两个equals对象。来自compareToequals的报告不一致将导致这种情况。

答案 1 :(得分:4)

简短回答:只要compareTo(a,b)为两个对象0a返回ba.equals(b)b.equals(a)应为true反之亦然。

答案很长:正如Comparable文档中所述,Comparable的实施强制执行总排序。其中一个properties of total ordering是“反对称”:如果我们定义总排序≤,那么:

  

如果a≤b且b≤a则a = b

这表示为0的{​​{1}}返回值。

此特征被您引用的文本中提到的方法和类利用,以获得更正确和有效的行为。

答案 2 :(得分:2)

您可以在Set的文档中看到它:

  

请注意由一组维护的排序(无论是否为   提供显式比较器)必须与equals 一致   如果要正确实现{@code Set}接口。 (看到   {@code Comparable}或{@code Comparator}用于精确定义   与equals 一致。)这是因为{@code Set}   接口是根据{@code equals}操作定义的,但是a   {@code TreeSet}实例使用它执行所有元素比较   {@code compareTo}(或{@code compare})方法,所以有两个元素   通过这种方法被认为是平等的,从集合的角度来看,   等于即可。集合的行为是,即使它是明确定义的   排序与equals不一致;它只是没有服从   {@code Set}界面的一般合约。