复数等于方法

Boa*_*ann 7 java equals complex-numbers

我在Java中创建一个复杂的数字类,如下所示:

public class Complex {
    public final double real, imag;

    public Complex(double real, double imag) {
        this.real = real;
        this.imag = imag;
    }

    ... methods for arithmetic follow ...
}
Run Code Online (Sandbox Code Playgroud)

我实现了这样的equals方法:

@Override
public boolean equals(Object obj) {
    if (obj instanceof Complex) {
        Complex other = (Complex)obj;
        return (
            this.real == other.real &&
            this.imag == other.imag
        );
    }
    return false;
}
Run Code Online (Sandbox Code Playgroud)

但是如果你重写equals,你也应该覆盖hashCode.其中一条规则是:

如果两个对象根据equals(Object)方法相等,则对两个对象中的每一个调用hashCode方法必须生成相同的整数结果.

比较floats和doubles进行==数值比较,因此+0.0 == -0.0NaN值不等于包括它们在内的所有东西.所以我尝试实现hashCode方法来匹配equals方法,如下所示:

@Override
public int hashCode() {
    long real = Double.doubleToLongBits(this.real); // harmonize NaN bit patterns
    long imag = Double.doubleToLongBits(this.imag);
    if (real == 1L << 63) real = 0; // convert -0.0 to +0.0
    if (imag == 1L << 63) imag = 0;
    long h = real ^ imag;
    return (int)h ^ (int)(h >>> 32);
}
Run Code Online (Sandbox Code Playgroud)

但后来我意识到如果任何一个字段是NaN,这在哈希映射中会奇怪地工作,因为它this.equals(this)总是假的,但也许这不是错误的.另一方面,我可以做什么Double,Float做什么,等于方法比较+0.0 != -0.0,但仍然协调不同的NaN位模式,然后让NaN == NaN,所以然后我得到:

@Override
public boolean equals(Object obj) {
    if (obj instanceof Complex) {
        Complex other = (Complex)obj;
        return (
            Double.doubleToLongBits(this.real) ==
                Double.doubleToLongBits(other.real) &&
            Double.doubleToLongBits(this.imag) ==
                Double.doubleToLongBits(other.imag)
        );
    }
    return false;
}

@Override
public int hashCode() {
    long h = (
        Double.doubleToLongBits(real) +
        Double.doubleToLongBits(imag)
    );
    return (int)h ^ (int)(h >>> 32);
}
Run Code Online (Sandbox Code Playgroud)

但如果我这样做,那么我的复数就不像实数那样+0.0 == -0.0.但我真的不需要将我的复杂数字放在哈希映射中 - 我只是想做正确的事情,遵循最佳实践等等.现在我只是感到困惑.有人可以告诉我最好的方法吗?

duf*_*ymo 0

病态的情况似乎是这样0.0 != -0.0,所以我会确保这种情况永远不会发生,并完全按照 Joshua Bloch 在“Effective Java”中告诉您的方式完成其余的工作。