Java での HashTables の実装を理解しようとしています。以下は私のコードです:
Hashtable<Integer, String> hTab = new Hashtable<Integer, String>();
hTab.put(1, "A");
hTab.put(1, "B");
hTab.put(2, "C");
hTab.put(3, "D");
Iterator<Map.Entry<Integer, String>> itr = hTab.entrySet().iterator();
Entry<Integer, String> entry;
while(itr.hasNext()){
entry = itr.next();
System.out.println(entry.getValue());
}
実行すると、以下の出力が得られます: D C B
これは、Key = 1; の衝突が発生したことを意味します。そして実装に従って:
「hashTable で衝突が発生するたびに、特定のバケットに対応する linkedList に新しいノードが作成され、EntrySet(Key, Value) のペアがノードとしてリストに格納され、新しい値がリストの先頭に挿入されます。特定のバケットについて」。そして、私はこの実装に完全に同意します。
しかし、これが本当なら、hashTable からエントリセットを取得しようとしたとき、「A」はどこに行ったのでしょうか?
繰り返しますが、独自の HashCode と equals メソッドを実装することで、これを理解するために以下のコードを試しました。そして驚くべきことに、これは HashTable の実装に従って完璧に機能します。以下は私のコードです:
public class Hash {
private int key;
public Hash(int key){
this.key = key;
}
public int hashCode(){
return key;
}
public boolean equals(Hash o){
return this.key == o.key;
}
}
public class HashTable1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Hashtable<Hash, String> hTab = new Hashtable<Hash, String>();
hTab.put(new Hash(1), "A");
hTab.put(new Hash(1), "B");
hTab.put(new Hash(2), "C");
hTab.put(new Hash(3), "D");
Iterator<Map.Entry<Hash, String>> itr = hTab.entrySet().iterator();
Entry<Hash, String> entry;
while(itr.hasNext()){
entry = itr.next();
System.out.println(entry.getValue());
}
}
}
出力 : D C B A
これは完璧です。Java での HashTable の動作におけるこのあいまいさを理解できません。
アップデート
@garrytan と @Brian: 返信ありがとうございます。しかし、私にはまだ少し疑問があります。
私の2番目のコードでは、正常に動作します。新しいキーである 2 つのオブジェクトを作成しました。これらは 2 つのオブジェクトであるため、この場合キーの衝突は発生せず、正常に動作します。私はあなたの説明に同意します。ただし、最初のコード セットで単純に「1」ではなく「new Integer(1)」を使用すると、まだ機能しませんが、現在 2 つのオブジェクトを作成しており、それらは異なるはずです。以下の簡単な行を書いてクロスチェックしました:
Integer int1 = new Integer(1);
Integer int2 = new Integer(1);
System.out.println(int1 == int2);
これは「False」を返します。つまり、キーの衝突は解決されているはずです。しかし、それでもうまくいきません。どうしてこれなの?