HashMapの配列の長さを2の累乗に設計する必要があるのはなぜですか?

  この記事を理解するための前提は、データ構造をある程度理解し、各データ構造の長所と短所を理解する必要があるということです。もちろん、HashMapの基礎となるデータ構造が配列+リンクリスト+赤黒木であることをすでに知っている場合は、それが適しています。初期化されたhashMapの配列の長さが16であることがわかっていて、容量が元の長さの2倍に拡張されるたびに、「あなたはすでに資格のあるギャングスターです」としか言えません。

 私は知りたいと思っている人ですが、「存在は意味がある」と思って大金を稼いでいるのですが、行き止まりになりやすいこともあります。OKナンセンス、トピックに移動します。

以下は、jdk1.8のHashMapのソースコードの一部です。

ここに画像の説明を挿入

ソースコードを通じて、HashMapの新しく追加された要素がモジュロ演算((array length-1)&key hashCode)によって計算されることがわかります(つまり、新しい要素のどの添え字位置を配列に配置する必要があるか)

ps:係数の計算についてはここでは説明しません。知りたい友達は自分でBaiduできます

次のプログラムは単純なシミュレーションで、配列の長さが15、16の場合、100要素で計算された添え字位置を追加します。これらの100個の要素に対応するハッシュコードは、それぞれ0〜100に増加します

  public static void main(String[] args) {
            int[] length={15,16};
            for(int n : length){
                System.out.println("--------------"+n+"-----------------");
                for(int hash=0;hash<=100;hash++){
                    System.out.print((hash & n-1)+"\t");
                }
                System.out.println();
            }  
  }
复制代码

結果は以下の通りです

ここに画像の説明を挿入

配列の長さが16の場合、16スロットが計算され、配列の各位置に均等に分散されます。配列の長さが15の場合、8スロットのみが計算され、各スロットが配置されることがわかります。 2ノードのリンクリストでは、8つのスロットがアイドル状態になります。この問題は一般にハッシュの競合と呼ばれ、非効率的なHashMapクエリを引き起こす可能性があります。マップからデータをフェッチする場合、キーによって計算されたスロットを通じて対応する要素を直接抽出できます。このスロットにはリンクリストが格納されているため、リンクリストを走査してデータを取得する必要があります。 (すべての要素のハッシュコードが同じ)の場合、HashMapはリンクされたリストに退化します。これは、配列のランダム検索が効率的であるような機能を失います。

したがって、配列の長さを2乗に等しくすると、ハッシュの衝突の確率を効果的に減らすことができます。

HashMapには多くの機能もありますが、興味がある場合は、JDKを参照して自分でHashMapを作成できます。ps:1.7 HashMapは比較的単純です。HashMapのソースコードを調べたい場合は、jdk1.7から始めることをお勧めします。

最後に、シンプルなHashMapblog.csdn.net/qq_39914581…を添付します。

おすすめ

転載: juejin.im/post/5e970f8d518825739837c70b