クラスのハッシュコードの実装があり、ハッシュコードの実装はEclipseが生成するものと一致しており、ここで説明されている最も一般的に受け入れられているプラクティスとも一致しています
これが私のハッシュコードの実装です(このメソッドで使用されるすべてのIDがオブジェクトのキーを構成します):
public int hashCode() {
final int prime = 31;
int hashCode = 1;
if(uId != null){
hashCode = prime * hashCode + uId.hashCode();
}
if(rId != null){
hashCode = prime * hashCode + rId.hashCode();
}
if(bId != null){
hashCode = prime * hashCode + bId.hashCode();
}
if(reId != null){
hashCode = prime * hashCode + reId.hashCode();
}
if(cId != null){
hashCode = prime * hashCode + cId.hashCode();
}
return hashCode;
}
非常に大規模なデータ セットをテストしていて、コレクションにこのクラスのオブジェクトの期待数がないというシナリオに遭遇しました。よく見ると、以下の 2 つのデータ セットは同じハッシュコード : 50268236873 になり、ハッシュコードが同じであるため、レコードはコレクションに追加された最後のレコードに置き換えられました。
Existing record :
Record@2c0781cd[uId=54046,rId=10967,bId=177,reId=1728,cId=50194]
Record being inserted into the collection :
Record@20dad050[uId=53806,rId=18389,bId=177,reId=19026,cId=50194]
Both of these had the hashCode value = 50268236873
したがって、質問:
1] これは、2 つの異なるオブジェクトのハッシュ コードが同じ値を持つ明確なケースです。では、これがどのデータセットでも起こらないようにする方法は? 素数は大きい方がいいですか?
2] 実装の hashCode 変数をよく見ると、最大値が 2^31 - 1 = 2147483647 である int データ型であり、上記のデータ セットに対して計算されるハッシュコード = 50268236873 よりも大きいため、オーバーフローが発生します。 . hashCode 値の型として long を使用する結果はありますか?
ありがとう
Nohsib
編集 :
私はHashSetを使用しており、投稿された回答を読んだ後、以下のようにequalsの実装を調べました.equalsでは、2つのオブジェクトのhashCodesが同じかどうかを確認し、それを使用してそれらが同じかどうかを判断するためだと思います.同じオブジェクトがこの問題を引き起こしています。
これを確認できる人はいますか?
@Override
public boolean equals(Object paramObject) {
boolean equals = false;
if (paramObject != null) {
ACRecord other = (ACRecord) paramObject;
if ((this.hashCode() == other.hashCode()) // I think this is where I am going wrong
|| (this.uId.equals(other.getUId())
&& this.rId.equals(other.getRId())
&& this.reId.equals(other.getReId())
&& this.bId.equals(other.getBId())
&& this.cId.equals(other.getCId))) {
equals = true;
}
}
return equals;
}
解決策 : hashCode を使用して 2 つのオブジェクトが等しいかどうかを判断したため、equals メソッドの実装が間違っていました。equals メソッドの実装を修正すると、ハッシュセットが既存のレコードを置き換えていたという問題が解決しました。