2つの等しくないオブジェクトが同じハッシュコードを持つ可能性があることは私の理解です。 HashMap Javaを追加または取得するときに、これはどのように処理されますか?
それらは同じバケットに追加されるだけで、equals()
はそれらを区別するために使用されます。各バケットには、同じハッシュコードを持つオブジェクトのリストを含めることができます。
理論的には、特定のクラスのオブジェクトのハッシュコードと同じ整数を返すことができますが、これは、ハッシュマップのパフォーマンス上の利点をすべて失い、実際にはオブジェクトをリストに格納することを意味します。
HashMapでは、キーとその連想値がバケットのリンクリストノードに格納され、キーはハッシュコードではなく、equals()メソッドを使用してハッシュマップで基本的に比較されます。
_hm.put("a","aValue"); // Suppose hashcode created for key "a" is 209
hm.put("b","bValue"); // Here hashcode created for key "b" is 209 as well.
_
a.equals(b)
がtrue
を返す場合、bValue
がaValue
を置き換え、bValue
が返されます。a.equals(b)
がfalse
を返す場合、バケットリストに別のノードが作成されるため、get("b")
を呼び出すと、a.equals(b)
がbValue
であるため、false
が取得されます。HashMapはハッシュとインデックスの概念に取り組んでいます。内部的にHashMapはノードの配列に値を格納します。各ノードはLinkedListとして動作します。
リンクリストの各ノードには4つの値があります。
int hash
K key
V value
Node<K, V> next
HashMapの内部構造:
HashMapに値を挿入するときに、Keyの最初のハッシュコードが生成され、いくつかのアルゴリズムに基づいてインデックスを計算します。
したがって、私たちの値は、次の要素のハッシュコード、キー、値、アドレスとともに特定のインデックスに格納されます。
HashMapから値を取得する際、最初にハッシュコードが生成され、次にインデックスが作成されます(挿入時と同じ方法)。インデックスから値を取得するとき、最初にハッシュコードをチェックします。ハッシュコードが一致する場合は、Nodeからのキーをチェックします。equalsメソッドを使用します。キーが一致する場合、それだけが値を返すか、次のチェックを行いますNode同じハッシュコードを使用します。
その場合、IdentityHashMapを使用できます。同じハッシュを持つ異なるオブジェクトは、それらのIDに基づいて異なるものと見なされます。
2つの等しくないオブジェクトのハッシュ値が同じである場合、両方のオブジェクトが同じスロット(バケットと呼ばれることもあります)に配置されるため、ハッシュテーブルで衝突が発生します。ハッシュアルゴリズムは、このような衝突を解決する必要があります。私の大学アルゴリズムコースの色あせた思い出に戻って、これを行う3つの基本的な方法を覚えています。
Javaハッシュクラスは3番目の方法を使用しますが、それらは組み合わせアプローチを使用する場合があります。ただし、ハッシュを適切に行うには、ハッシュテーブルに十分な容量を確保し、適切に書き込むことが重要です。ハッシュ関数。保持しているオブジェクトと同じ数のバケットしか持たないハッシュテーブルでは、おそらく競合が発生します。通常、ハッシュテーブルは、格納するオブジェクトの数の約2倍にする必要があります。JavaのHashMapは必要に応じて拡大しますが、必要に応じて、開始容量と負荷係数を指定できます。
ハッシュ関数はプログラマ次第です。すべてのオブジェクトに対して単に0を返すこともできますが、これはハッシュ(格納と取得の両方)がO(n)ではなくO(1)になることを意味します。 = ...または一言で言えば、それは遅い犬になります。
リファレンス: http://www.coderanch.com/t/540275/Java/java/objects-hashcode-HashMap-retrieve-objects