しかし、Java の一般的な連絡先によると、同じ値を返す必要があります。
Java のequals-hashCode
契約では、2 つのオブジェクトが で等しい場合Object.equals
、それらは からの同じハッシュコードを持っている必要がありますObject.hashCode
。ただし、デフォルトの実装Object.equals
は参照等価であるため、2 つのインスタンスが同じである場合は、それらが同じインスタンスである場合に限ります。
したがって、特に 2 つのインスタンスt1
とt2
は、オーバーライドしていないため、実際には等しくありませんObject.equals
。これらは参照として等しくないため、 ごとObject.equals
に等しくないため、 がhashCode
異なる値を返す可能性があります。実際、契約には次のように明示的に記載されています。
2 つのオブジェクトがメソッドによって等しくない場合、2 つのオブジェクトのそれぞれでメソッドequals(java.lang.Object)
を呼び出すと、hashCode
異なる整数結果が生成される必要はありません。
equals-hashCode
したがって、ここでは契約違反はありません。
したがって、オブジェクトについて、等価性の論理定義に従って異なるインスタンスを等しくしたい場合は、オーバーライドする必要がありますObject.equals
。
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
if (this == obj) {
return true;
}
if (!(obj instanceof Test)) {
return false;
}
Test other = (Test)obj;
return this.i == other.i && this.j == other.j;
}
また、equals-hashCode
契約ではオーバーライドObject.hashCode
も必要です。そうしないと、厄介なバグに遭遇します。
@Override
public int hashCode() {
int hash = 17;
hash = 31 * hash + this.i;
hash = 31 * hash + this.j;
return hash;
}
契約書の内容:
メソッドに従って 2 つのオブジェクトが等しい場合、2 つのオブジェクトのそれぞれでメソッドequals(Object)
を呼び出すとhashCode
、同じ整数の結果が生成される必要があります。
ここで、この要件を満たしているかどうかを見てみましょう。x
とy
が のインスタンスであり、 がTest
を満たす場合、 とがあります。次に、明らかに、呼び出して、実行の各行で同じ値を保持する不変式がある場合。どちらの場合もそうであるため、明らかにこれは最初の行に当てはまります。が等しいかどうかにかかわらず同じ値を返すため、2 行目に保持されます。最後に、最後から 2 番目の行では、equalsも true であるため、両方の呼び出しで等しいままです。x.equals(y)
true
x.i == y.i
x.j == y.j
x.hashCode()
y.hashCode()
Test.hashCode
hash
hash
17
this.i
this == x
this == y
x.i
y.i
hash
x.j
y.j
まだ説明していないコントラクトの最後の部分があることに注意してください。hashCode
これは、Java アプリケーションの 1 回の実行中に一貫した値を返すという要件です。
hashCode
オブジェクトの equals 比較で使用される情報が変更されていない限り、メソッドは、Java アプリケーションの実行中に同じオブジェクトに対して複数回呼び出されるたびに、一貫して同じ整数を返す必要があります。
これの必要性は明らかです。hashCode
同じアプリケーションの 1 回の実行中に戻り値を変更するとhashCode
、オブジェクトの追跡に使用されるハッシュテーブルのようなデータ構造でオブジェクトが失われる可能性があります。特に、これが、ハッシュテーブルのようなデータ構造のキーであるオブジェクトを変更することが純粋な悪である理由です。しないでください。私は、それらが不変オブジェクトであるべきだと主張するところまで行きます。
実際、私が同じことをしているとき、String
またはInteger
彼らが同じを返しているときhashcode()
。
それらは両方ともオーバーライドさObject.equals
れており、Object.hashCode
.