web-dev-qa-db-ja.com

2つの異なるオブジェクトが同じハッシュコードを持っている場合はどうなりますか?

2つの等しくないオブジェクトが同じハッシュコードを持つ可能性があることは私の理解です。 HashMap Javaを追加または取得するときに、これはどのように処理されますか?

18
Joey

それらは同じバケットに追加されるだけで、equals()はそれらを区別するために使用されます。各バケットには、同じハッシュコードを持つオブジェクトのリストを含めることができます。

理論的には、特定のクラスのオブジェクトのハッシュコードと同じ整数を返すことができますが、これは、ハッシュマップのパフォーマンス上の利点をすべて失い、実際にはオブジェクトをリストに格納することを意味します。

28
Alex Gitelman

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を返す場合、bValueaValueを置き換え、bValueが返されます。
  • a.equals(b)falseを返す場合、バケットリストに別のノードが作成されるため、get("b")を呼び出すと、a.equals(b)bValueであるため、falseが取得されます。
7
Yash

HashMapはハッシュとインデックスの概念に取り組んでいます。内部的にHashMapはノードの配列に値を格納します。各ノードはLinkedListとして動作します。

リンクリストの各ノードには4つの値があります。

  1. int hash
  2. K key
  3. V value
  4. Node<K, V> next

HashMapの内部構造:

HashMap Internal structure Image

HashMapに値を挿入するときに、Keyの最初のハッシュコードが生成され、いくつかのアルゴリズムに基づいてインデックスを計算します。

したがって、私たちの値は、次の要素のハッシュコード、キー、値、アドレスとともに特定のインデックスに格納されます。

HashMapから値を取得する際、最初にハッシュコードが生成され、次にインデックスが作成されます(挿入時と同じ方法)。インデックスから値を取得するとき、最初にハッシュコードをチェックします。ハッシュコードが一致する場合は、Nodeからのキーをチェックします。equalsメソッドを使用します。キーが一致する場合、それだけが値を返すか、次のチェックを行いますNode同じハッシュコードを使用します。

1
Gaurav Lal

その場合、IdentityHashMapを使用できます。同じハッシュを持つ異なるオブジェクトは、それらのIDに基づいて異なるものと見なされます。

0
kenmar

2つの等しくないオブジェクトのハッシュ値が同じである場合、両方のオブジェクトが同じスロット(バケットと呼ばれることもあります)に配置されるため、ハッシュテーブルで衝突が発生します。ハッシュアルゴリズムは、このような衝突を解決する必要があります。私の大学アルゴリズムコースの色あせた思い出に戻って、これを行う3つの基本的な方法を覚えています。

  1. ハッシュテーブルで次の空のスロットを探し、そこにオブジェクトを配置します。長所:実装が簡単、短所:オブジェクトのクラスター化につながり、パフォーマンスが低下する可能性があり、容量を超える可能性があります
  2. 競合がある場合に使用する2次ハッシュ関数を用意する:長所:通常は高速、短所: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

0
supernova