使用compareTo实现equals方法
一般问题:在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上的文档
当且仅当e1.compareTo(e2)== 0与c1的每个e1和e2的e1.equals(e2)具有相同的布尔值时,C类的自然排序被认为与equals一致。 null不是任何类的实例,并且e.compareTo(null)应抛出NullPointerException,即使e.equals(null)返回false
编辑:
经过进一步审查后,我发现可比较文件还说明了以下内容:
实现者必须确保所有x和y的sgn(x.compareTo(y))== -sgn(y.compareTo(x))。 (这意味着如果y.compareTo(x)抛出exception,x.compareTo(y)必须抛出exception。)
因为null.compareTo(x)
显然会抛出一个NPE , x.compareTo(null)
应该抛出一个NPE。 而对于平等,情况不一定如此。 我对NPE的正确处理非常重视,所以我发现这个相对重要。
equals()
和compareTo()
之间的区别在于equals()
只是检查两个对象是否彼此相等,其中compareTo()
用于标识指定类的实例的自然顺序。 equals()
方法也与hashCode()
equals()
方法有一个契约,但compareTo()
却没有。
根据JavaDoc :
请注意,null不是任何类的实例,并且即使e.equals(null)返回false,e.compareTo(null)也应抛出NullPointerException。
强烈建议,但并非严格要求(x.compareTo(y)== 0)==(x.equals(y))。 一般来说,任何实现Comparable接口并且违反此条件的类都应该清楚地表明这一事实。 推荐的语言是“注意:此类具有与equals不一致的自然顺序。”
您可以随意在compareTo()
方法中重用compareTo()
方法逻辑,但要记住equals()
, hashCode()
所有契约以及来自JavaDoc for compareTo()
方法的契约。 如果他们不相互冲突,那就继续吧。
我认为合同的执行更为重要。
compareTo
可能涉及比获得平等答案所需的更多工作,这可能最终成为性能问题,具体取决于您的应用程序使用情况。
除此之外,遵循DRY原则,按照您的建议重新使用代码是个好主意。