データ構造
HashMap
採用されたデータ構造=配列(メイン)+単一リンクリスト(サブ)
HashMapの主な構造は配列に似ています。値を追加する場合、格納場所はキーによって決定されます。各場所はエントリデータ構造です。この構造はリンクリストを形成できます。競合が発生すると、同じハッシュ値のキーと値のペアがリンクリストを形成します。 。
この配列+リンクリストの組み合わせは、ほとんどの場合に良好なパフォーマンスを発揮します。Java6と7はこのように設計されていますが、極端な場合、一連の(慎重に設計された)キーと値のペアが発生しました。競合が発生した場合、この時点でのハッシュ構造はリンクリストに縮退し、HashMapのパフォーマンスが大幅に低下します。
putメソッド
/ ** *指定された値をこのマップ内の指定されたキーに関連付けます。 *マップに以前にキーのマッピングが含まれていた場合、古い 値が*置き換えられます。 * * @paramの指定された値が関連付けられるキーキー * @paramのキー指定に関連付けられる値値 *を@return <TT>キー</ TT>に関連付けられた以前の値、または * <TT>ヌル</ tt> <tt> key </ tt>のマッピングがなかった場合。 *(<tt> null </ tt>の戻り値は、マップが 以前に<tt> null </ tt>を<tt> key </ tt>に関連付けていたことを示すこともできます。 V put(K key、V value){ // 配列が空の場合、初期化を実行します。 if(table == EMPTY_TABLE){ inflateTable(threshold); } if(key == null ) // キーが空の場合、値を配列の位置0に移動し、 return putForNullKey(value ); // キーのハッシュ値を計算する int hash = hash(key); // ハッシュ値とデータを格納する配列の長さに基づいて位置インデックスを計算する int i = indexFor(hash、table.length); // 対応する位置にあるかどうかを調べる値は、値が新しい値に置き換えられた場合 のために(エントリ<K、V>表E = [I] ;! E = NULL ; E = e.next){ オブジェクトk; if(e.hash == hash &&((k = e.key)== key || key.equals(k))){ V oldValue = e.value; e.value = value; // HashMap空の実装、無視できる e.recordAccess(this ); return oldValue; } } // レコードの変更時間に1を加えた modCount ++ ; // キーと値のマッピングを配列に追加 addEntry(hash、key、value、i); return null ; }
配列メソッドinflateTableを初期化する
/ ** *テーブルをインフレートします * / Private void inflateTable(int toSize){ // 2のべき乗を見つける> = toSize // toSizeよりも大きい 2 の最小のべき乗を 見つけます(例:toSize = 23、次に容量) 2 ^ 6 = 32 int capacity = roundUpToPowerOf2(toSize); // 容量と負荷係数に従って拡張しきい値を計算します。容量がこのしきい値に達すると、HashMapが容量を拡張します。 threshold =(int)Math.min(capacity * loadFactor、MAXIMUM_CAPACITY + 1 ); // EntiEntry <K、V> []配列ストレージサイズ テーブルを初期化 = new Entry [capacity]; // HashSeed initHashSeedAsNeeded(capacity); }を初期化
お振込方法
void transfer(Entry [] newTable、boolean rehash){ int newCapacity = newTable.length; for(Entry <K、V> e:table){ while(null!= e){ Entry <K、V> next = e.next; if (rehash){ e.hash = null == e.key?0 :hash(e.key); } int i = indexFor(e.hash、newCapacity); e.next = newTable [i]; newTable [i] =e; e = 次; } } }
このコードはHashMap
拡張操作であり、各バケットの添え字を再配置し、ヘッド補間を使用して要素を新しい配列に移行します。ヘッド補間法は、リンクされたリストの順序を逆にします。これは、無限ループを形成するための重要なポイントでもあります。ヘッドの挿入方法を理解したら、エンドレスループとデータ損失を引き起こす方法を見下ろし続けます。
https://blog.csdn.net/carson_ho/article/details/79373026
https://cloud.tencent.com/developer/article/1489931
https://www.nowcoder.com/discuss/151172
https://www.cnblogs.com/yangyongjie/p/11015174.html