equals()方法存在于Comparator接口中,但它在Comparable接口中不存在。为什么?此外,根据equals()和hashcode()之间的契约,两者都必须被覆盖,而在Comparator中则不是这样。为什么?任何人都可以帮助我理解它背后的概念。
答案 0 :(得分:2)
equals()方法存在于Comparator接口中,但它在Comparable接口中不存在。为什么呢?
Comparator.equals(...)用于测试对象是否等于到此比较器;用于测试两个可比较对象是否相等的不。 (这就是为什么它需要一个Object
,而不是两个T
- s。)因为比较器声明它,并不意味着Comparable有任何理由声明它。
那就是说,仍然值得问为什么比较器声明它,因为比较器(像每种类型)已经是Object的子类型。原因很简单,Comparator想要对equals(...)施加一些额外的要求,因此它需要提供特定的Javadoc。 (具体来说,它要求两个比较器永远不会被认为是相等的,除非它们实现相同的顺序。比较器的实现可以通过使用Object中的equals(...)或通过定义自定义等于(...)来满足此要求。这更精确。)
此外,根据equals()和hashcode()之间的契约,两者都必须被覆盖,而在Comparator中则不是这样。
比较器实际上并不“覆盖”等于(...)。 Comparator的实现者仍然继承Object.equals(...),除非它们覆盖它。
由于Comparator没有提供equals()的实际实现 - 它只是指定了一些额外的要求 - 它不需要对hashCode()说任何特别的东西。 hashCode()的一般契约以及hashCode()与equals()的关系仍然适用。
答案 1 :(得分:1)
实现Comparable的类已经有一个从Object继承的equals方法,而Comparable对equals()没有额外的约束。
比较器要求,对于MyComparatorType.equals(Comparator other)返回true,我的比较器和另一个比较器都采用相同的顺序。这允许一些性能改进和优化,并且如果违反此特殊合同,可能会在某些时候导致运行时异常。
来自the Comparator javadoc的相关行:
指示某个其他对象是否“等于”此比较器。此方法必须遵守Object.equals(Object)的常规协定。
此外,仅当指定的对象也是比较器并且它与此比较器施加相同的顺序时,此方法才能返回true。因此,comp1.equals(comp2)意味着每个对象引用o1和o2的sgn(comp1.compare(o1,o2))== sgn(comp2.compare(o1,o2))。
请注意,不要覆盖Object.equals(Object)总是安全的。但是,在某些情况下,通过允许程序确定两个不同的比较器强加相同的顺序,覆盖此方法可能会提高性能。
因此Comparator 应该遵循与实现Object.equals(Object)的任何其他事物相同的合同,其中包括正确的hashCode()行为。
答案 2 :(得分:0)
equals(Object obj)
出现在所有课程中。它来自Object
类。
在Comparator
界面中,添加了equals(Object obj)
声明以覆盖相关的javadoc,以便客户端知道有兴趣覆盖此的equals()
方法类。这是一个提示。
比较器中equals(Object obj)
的Javadoc:
指示某个其他对象是否“等于”此比较器。 此方法必须遵守Object.equals(Object)的常规协定。 此外,此方法只有在指定的对象时才能返回true 也是一个比较器,它的排序与此相同 比较。因此,comp1.equals(comp2)意味着 sgn(comp1.compare(o1,o2))== sgn(comp2.compare(o1,o2)) 对象引用o1和o2。
请注意,不要覆盖Object.equals(Object)总是安全的。 但是,在某些情况下,覆盖此方法可能会有所改善 通过允许程序确定两个不同的性能 比较器强制执行相同的命令。
有什么意义?
想象你必须使用不同的比较器多次调用Collections.sort()
方法。如果两个比较器是等于()并且您已经应用了一个比较器,则不应该应用第二个比较器,因为它不起作用。如上所述,这是一个暗示。
在Comparable
中,JDK开发人员判断无法添加有关equals
方法覆盖的任何信息。对象的equals(Object obj)
Javadoc应该足够了。