equals
および をオーバーライドするときには、どのような問題や落とし穴を考慮する必要がありますかhashCode
?
ベストアンサー1
理論(言語法の専門家と数学に興味のある人向け):
equals()
(javadoc) は同値関係を定義する必要があります (反射的、対称的、推移的である必要があります)。さらに、一貫性も必要です(オブジェクトが変更されていない場合、同じ値を返し続ける必要があります)。さらに、o.equals(null)
常に false を返す必要があります。
hashCode()
(javadoc) も一貫している必要があります(オブジェクトが に関して変更されていない場合equals()
、同じ値を返し続ける必要があります)。
2 つの方法の関係は次のとおりです。
のときは常に
a.equals(b)
、a.hashCode()
と同じでなければなりませんb.hashCode()
。
実際には:
一方をオーバーライドする場合は、もう一方もオーバーライドする必要があります。
equals()
計算に使用するのと同じフィールド セットを使用して を計算しますhashCode()
。
優れたヘルパークラスを使用するイコールビルダーそしてハッシュコードビルダーからApache Commons言語ライブラリ。例:
public class Person {
private String name;
private int age;
// ...
@Override
public int hashCode() {
return new HashCodeBuilder(17, 31). // two randomly chosen prime numbers
// if deriving: appendSuper(super.hashCode()).
append(name).
append(age).
toHashCode();
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Person))
return false;
if (obj == this)
return true;
Person rhs = (Person) obj;
return new EqualsBuilder().
// if deriving: appendSuper(super.equals(obj)).
append(name, rhs.name).
append(age, rhs.age).
isEquals();
}
}
また、次の点も覚えておいてください:
ハッシュベースのコレクションまたは地図のようなハッシュセット、リンクハッシュセット、ハッシュマップ、ハッシュ表、 または弱いハッシュマップコレクションに入れたキーオブジェクトのhashCode()が、オブジェクトがコレクション内にある間は決して変更されないことを確認してください。これを確実にする確実な方法は、キーを不変にすることです。他にも利点がある。