これはいくつかの光を当てるかもしれません(Oracle Webサイトから取得):
実装上の注意: これは、Sedgewick と Knuth によるテキストなどで説明されている単純な線形プローブ ハッシュ テーブルです。配列はキーと値を交互に保持します。(これは、個別の配列を使用するよりも、大きなテーブルの局所性が優れています。)多くの JRE 実装と操作の組み合わせでは、このクラスは HashMap (線形プローブではなく連鎖を使用) よりも優れたパフォーマンスをもたらします。
ほとんどの実装ではチェーンの方が適しているかもしれませんが、すべての実装でそうであるとは限りません。
編集これも見つかりました。おそらくそれほど重要ではありません(ここから取得):
プローブを使用する動機は、リンクされたリストをたどるよりもいくらか高速であるということですが、これは、値への参照を配列に直接配置できる場合にのみ当てはまります。他のすべてのハッシュベースのコレクションでは、値だけでなくハッシュ コードも格納されるため、これは実用的ではありません。これは効率上の理由によるものです。get 操作では、正しいキーが見つかったかどうかを確認する必要があります。また、等価性はコストのかかる操作であるため、正しいハッシュ コードがあるかどうかを最初に確認するのが理にかなっています。もちろん、この推論はIdentityHashMap
、オブジェクトの等価性ではなくオブジェクトの同一性をチェックする には当てはまりません。
背景/明確化として、 は、2 つのキーが物理的に同じオブジェクトである場合にのみ等しいと見なされるというIdentityHashMap
点で、通常HashMap
のキーとは異なります。キーの比較には、等しいではなく、同一性が使用されます。
EDIT:答えを見つけるのに役立つ議論(以下のコメントから):
しようとしている:
ただし、これは、値への参照を配列に直接配置できる場合にのみ当てはまります。他のすべてのハッシュベースのコレクションでは、値だけでなくハッシュ コードも格納されるため、これは実用的ではありません。リンクされたリストのトラバーサルが直接配列よりもコストがかかる場合、hashMap がキー、値、およびハッシュコードを配列に入れ、線形プローブを使用できないのはなぜでしょうか?
wlyles:
スペースの使用が原因である可能性があります。これは、各スロットでより多くのデータを占有します。また、トラバーサルは線形プローブの場合はコストがかからないことを指摘しておく必要がありますが、線形プローブは多くのキーが同じハッシュ値を持つクラスタリングに悩まされることが多いため、全体の検索操作はよりコストがかかる (そして予測しにくい) 可能性があります。@delnan が別のコメントで述べたように、たとえば、キー 1..20 が連続するスロットにハッシュされ、21 番目が 1 番目と同じスロットにハッシュされる場合、それを検索します (または、 1 番目のスロット) には 20 個のプローブが必要です。リストを使用すると、必要なプローブが少なくなります。さらに明確にするために: IdentityHashMap がキー値を比較する方法により、衝突の可能性は非常に低くなります。したがって、線形プロービングの主な弱点である凝集につながる衝突が大幅に回避されます。
さらに明確にするために: IdentityHashMap がキー値を比較する方法により、衝突の可能性は非常に低くなります。したがって、線形プローブの主な弱点である凝集につながる衝突が大幅に回避され、この実装でより望ましいものになります。