来自Comparator和Comparable的compare和compareTo方法的契约

时间:2015-02-10 03:28:30

标签: java comparator comparable

实施ComparatorComparable接口时,是否需要确保:

如果

  • x.compare(Object obj1, Object obj2) == x.compare(Object obj3, Object obj2)

  • obj1.compareTo(obj2) == obj3.compareTo(obj2)

然后obj1.equals(obj3)必须是true

2 个答案:

答案 0 :(得分:1)

不一定。

您要描述的是三个给定对象之间的transitive relationas far as both of the interfaces关注,使用它们时的关系必须他们之间传递。

这就是说,给定三个类ABC相互比较,如果A.compareTo(B) == 0 && B.compareTo(C) == 0,则A.compareTo(C) == 0。同样的原则适用于Comparator

您现在正在混淆的是compareToequals之间的区别。虽然这两者密切相关,但没有任何内容可以强制执行文档中提供的very strong recommendation

  

强烈建议,但并非严格要求(x.compareTo(y)==0) == (x.equals(y))。一般来说,任何实现Comparable接口并违反此条件的类都应清楚地表明这一事实。建议的语言为"注意:此类具有与equals不一致的自然顺序。"

equals定义与compareTo甚至compare不一致当然是可行且有效的,但根据程序的性质,它可能会导致模糊的错误。如果您发现自己处于需要依赖equalscompareTo(或compare)的情况,请记录并与其使用保持一致。

答案 1 :(得分:0)

不,因为两个对象的比较只能确定一个大于,等于或小于另一个。通常,比较器返回的结果是(-1,0,1)之一。例如:

comparator.compare(1,5) == -1
comparator.compare(1,3) == -1
comparator.compare(3,1) == 1
comparator.compare(5,3) == 1
comparator.compare(3,3) == 0

这使开发人员更容易在对象之间进行比较。如果合同要求返回差异的比例,那么为字符串实现这样的方法将非常困难。为了获得精确的值差异,必须读取两个字符串的全部内容,这可能对性能非常不利,特别是如果这些字符串中的每一个都非常大。因为只需要确定哪个比另一个大,所以通常只需要比较一小部分字符串以确定哪个字符串更大"比另一个。整个字符串必须处理的唯一时间是它们实际上是相等的。这个性能问题也是为什么哈希是可取的,如果可能的话