关于java:使用compareTo实现equals方法

Implementing equals method using compareTo

一般问题:当在Java中实现对默认EDCOX1 0Ω方法的重写时,对于简单地利用已经实现的EDCOX1×1的方法与将独立逻辑写入到相等方法中,我应该考虑什么?我注意到有人在另一个问题中提到,foo.equals((String)null)返回错误,而String.compareTo((String)null)抛出NullPointerException。是什么使这些不一致的结果成为理想的功能?

样品equals法:

1
2
3
4
5
6
7
8
@Override
public boolean equals(Object obj) {
    if (obj != null && obj instanceof MyClass) {
        MyClass msg = (MyClass)obj;
        return this.compareTo(msg) == 0;
    }
    return false;
}

编辑:从可比文件中引用

The natural ordering for a class C is said to be consistent with
equals if and only if e1.compareTo(e2) == 0 has the same boolean value
as e1.equals(e2) for every e1 and e2 of class C. Note that null is not
an instance of any class, and e.compareTo(null) should throw a
NullPointerException even though e.equals(null) returns false

编辑:

在进一步审查后,我发现值得注意的是,可比文件还规定了以下内容:

The implementor must ensure sgn(x.compareTo(y)) == -sgn(y.compareTo(x)) for all x and y. (This implies that x.compareTo(y) must throw an exception iff y.compareTo(x) throws an exception.)

因此,由于null.compareTo(x)显然会抛出一个NPE,所以x.compareTo(null)也应该抛出一个NPE。而对于平等者来说,情况并不一定如此。我对NPE的正确处理相当在行,所以我发现这一点相对重要。


compareTo可能需要比仅仅为了得到一个相等的答案所需要的更多的工作,这最终可能是一个性能问题,具体取决于您的应用程序使用情况。

除此之外,遵循干燥的原则,如您所建议的,重新使用代码是一个好主意。


equals()compareTo()的区别在于,equals()只是检查两个对象是否相等,其中compareTo()用于标识指定类实例的自然顺序。另外,equals()法与hashCode()法有约定,但compareTo()法没有。

根据JavaDoc:

Note that null is not an instance of any class, and e.compareTo(null)
should throw a NullPointerException even though e.equals(null) returns
false.

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()方法逻辑,但请记住所有与equals()hashCode()和javadoc对compareTo()方法的契约。如果他们之间没有冲突,那就继续吧。

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