Comparator 和 Comparable 的 compare 和 compareTo 方法的契约
Contracts of the compare and compareTo method from Comparator and Comparable
实现Comparator
和Comparable
接口时,是否需要保证:
如果
x.compare(Object obj1, Object obj2) == x.compare(Object obj3, Object obj2)
或
obj1.compareTo(obj2) == obj3.compareTo(obj2)
,
那么obj1.equals(obj3)
一定是true
?
不,因为两个对象的比较只确定一个大于、等于或小于另一个。通常从比较器返回的结果是 (-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
这使得开发人员更容易比较对象。如果合同要求返回差异的比例,则很难为字符串等实现这种方法。为了获得精确的值差异,必须读取两个字符串的全部内容,这可能对性能非常不利,尤其是如果这些字符串中的每一个都非常大。因为只需要确定哪个比另一个大,通常只需要比较字符串的一小部分来确定哪个比另一个大 "larger"。唯一需要处理整个字符串的情况是它们实际上是否相等。这个性能问题也是在可能的情况下首选散列的原因
不一定。
你说的是transitive relation between three given objects, and as far as both of the interfaces,使用它们时的关系必须在它们之间是可传递的。
也就是说,给定三个类、A
、B
、C
三个可以相互比较的,若A.compareTo(B) == 0 && B.compareTo(C) == 0
,则A.compareTo(C) == 0
。同样的原则适用于 Comparator
.
您现在混淆的是 compareTo
和 equals
之间的区别。虽然这两者密切相关,但没有任何内容可以强制执行文档中提供的 very strong recommendation:
It is strongly recommended, but not strictly required that (x.compareTo(y)==0) == (x.equals(y)
). Generally speaking, any class that implements the Comparable
interface and violates this condition should clearly indicate this fact. The recommended language is "Note: this class has a natural ordering that is inconsistent with equals."
equals
定义与 compareTo
甚至 compare
不一致当然是可能且有效的,但根据程序的性质,它可能会导致模糊的错误.如果您发现自己处于需要同时依赖 equals
和 compareTo
(或 compare
)的情况,请将其记录下来并与其用法保持一致。
实现Comparator
和Comparable
接口时,是否需要保证:
如果
x.compare(Object obj1, Object obj2) == x.compare(Object obj3, Object obj2)
或
obj1.compareTo(obj2) == obj3.compareTo(obj2)
,
那么obj1.equals(obj3)
一定是true
?
不,因为两个对象的比较只确定一个大于、等于或小于另一个。通常从比较器返回的结果是 (-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
这使得开发人员更容易比较对象。如果合同要求返回差异的比例,则很难为字符串等实现这种方法。为了获得精确的值差异,必须读取两个字符串的全部内容,这可能对性能非常不利,尤其是如果这些字符串中的每一个都非常大。因为只需要确定哪个比另一个大,通常只需要比较字符串的一小部分来确定哪个比另一个大 "larger"。唯一需要处理整个字符串的情况是它们实际上是否相等。这个性能问题也是在可能的情况下首选散列的原因
不一定。
你说的是transitive relation between three given objects, and as far as both of the interfaces,使用它们时的关系必须在它们之间是可传递的。
也就是说,给定三个类、A
、B
、C
三个可以相互比较的,若A.compareTo(B) == 0 && B.compareTo(C) == 0
,则A.compareTo(C) == 0
。同样的原则适用于 Comparator
.
您现在混淆的是 compareTo
和 equals
之间的区别。虽然这两者密切相关,但没有任何内容可以强制执行文档中提供的 very strong recommendation:
It is strongly recommended, but not strictly required that (
x.compareTo(y)==0) == (x.equals(y)
). Generally speaking, any class that implements theComparable
interface and violates this condition should clearly indicate this fact. The recommended language is "Note: this class has a natural ordering that is inconsistent with equals."
equals
定义与 compareTo
甚至 compare
不一致当然是可能且有效的,但根据程序的性质,它可能会导致模糊的错误.如果您发现自己处于需要同时依赖 equals
和 compareTo
(或 compare
)的情况,请将其记录下来并与其用法保持一致。