一般问题:在Java中实现对默认equals
方法的覆盖时,我应该关注简单地利用已经实现的compareTo
方法与将独立逻辑写入equals方法?我注意到有人在另一个问题中提到foo.equals((String)null)
返回false,而String.compareTo((String)null)
则抛出NullPointerException
。是什么让这些不一致的结果成为理想的功能?
示例equals
方法:
@Override
public boolean equals(Object obj) {
if (obj != null && obj instanceof MyClass) {
MyClass msg = (MyClass)obj;
return this.compareTo(msg) == 0;
}
return false;
}
修改 引自Comparable
上的文档C类的自然排序据说是一致的 当且仅当e1.compareTo(e2)== 0具有相同的布尔值时才等于 作为类C的每个e1和e2的e1.equals(e2)。注意null不是 任何类的实例,e.compareTo(null)应抛出一个 即使e.equals(null)返回false
,也会出现NullPointerException
修改
经过进一步审核后,我发现Comparable文档还说明了以下内容:
实现者必须确保所有x和y的sgn(x.compareTo(y))== -sgn(y.compareTo(x))。 (这意味着如果y.compareTo(x)抛出异常,x.compareTo(y)必须抛出异常。)
因为null.compareTo(x)
显然会引发NPE,x.compareTo(null)
也会引发NPE。而对于平等,情况不一定如此。我对NPE的正确处理非常重视,所以我发现它相对重要。
答案 0 :(得分:9)
compareTo
可能涉及的工作量远远超过获得平等答案所需的工作量,可能最终成为性能问题,具体取决于您的应用程序使用。
除此之外,遵循DRY原则,按照您的建议重新使用代码是个好主意。
答案 1 :(得分:6)
equals()
和compareTo()
之间的区别在于equals()
只检查两个对象是否彼此相等,其中compareTo()
用于标识自然顺序指定类的实例。此外,equals()
方法与hashCode()
方法签订了合同,但compareTo()
没有。
根据JavaDoc:
请注意,null不是任何类的实例,而e.compareTo(null) 即使e.equals(null)返回,也应抛出NullPointerException 假的。
强烈建议,但并非严格要求 (x.compareTo(y)== 0)==(x.equals(y))。一般来说,任何课程 实现Comparable接口并违反此条件 应该清楚地表明这一事实。推荐的语言是“注意: 这个类的自然顺序与equals不一致。“
您可以随意在compareTo()
方法中重用equals()
方法逻辑,但请记住equals()
,hashCode()
的所有合同以及来自JavaDoc for {的合同{1}}方法。如果他们不相互冲突,那就继续吧。
我认为合同的执行更为重要。