使用compareTo实现equals方法

时间:2013-05-29 14:36:05

标签: java equals compareto

一般问题:在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)显然会引发NPEx.compareTo(null)也会引发NPE。而对于平等,情况不一定如此。我对NPE的正确处理非常重视,所以我发现它相对重要。

2 个答案:

答案 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}}方法。如果他们不相互冲突,那就继续吧。

我认为合同的执行更为重要。