ハッシュマップソースコード解析の研究ノート

もしjava7とハッシュマップソースコード解析のjava8、

1.ブログを表示します。

https://www.cnblogs.com/jajian/p/10385063.html#autoid-0-0-0

2.文字クラスのない感覚は、あなたがビデオを見ることができない場合:

https://www.bilibili.com/video/av71408100?from=search&seid=805805466626935035

以下は、自己学習ノートの要約であります

1.java7、HashMapの構成(配列+鎖)

 

2.「モジュロ」動作は、操作の変位モードを使用してハッシュ値を比較的大きな消費します

静的 INT indexFor(INT H、int型の長さ){  
    戻り H&(長さ1 )。  
}  

3.ハッシュ衝突(ハッシュコード、この場合は、ハッシュ衝突と呼ばれる同一の2つの異なるオブジェクトの場合)、単独の単鎖構造を生成する(ハッシュ値は、単一のチェーン店を作成する同じ配列内に一般の場合)

 

 

 

4.hashmap 3つのパラメータは、ソースを示しています

定員:配列の電流容量は、常に拡張することができ、配列の現在のサイズに拡張後の二回、2 ^ n個を保ちます。
loadFactor:負荷率、デフォルト0.75(要素のフィルハッシュテーブルの程度を表す負荷率)です。
しきい値:拡張しきい値、同じ容量* loadFactor。

ソースコード解析

パブリックVのPUT(鍵K、V値){
     // 最初のエレメントに挿入、配列サイズ初期化する必要が
    IF(表== EMPTY_TABLE){ 
        inflateTable(閾値); 
    } 
    // キーがnullの場合、関心[0]で、これはテーブルに最後のエントリになり、内部を見ることができる
    IF(キー==のNULL を返すputForNullKey(値);
     // 1は、ハッシュ値のキーシーク
    int型のハッシュ= ハッシュ(キー);
     // 2.対応する配列のインデックスを見つける
    int型 I = indexFor(ハッシュ、table.length);
     // 、重複キーが存在しているかどうかを確認するための指標を見に対応するリンクリストトラバース3.
     //     もしあれば、直接カバレッジ、 putメソッドは、古い値を超えている返す
    ために(!エントリー<K、V>表E = [I]、Eは= ヌル ; Eは= e.next){ 
        オブジェクトK; 
        IF = e.key(ハッシュをe.hash == &&((K)==キー| | key.equals(K))){ 
            V OLDVALUE = e.Value; 
            e.Value = 値; 
            e.recordAccess(これは、)
             を返すOLDVALUEを; 
        } 
    } 

    ModCount ++ ;
     // 4.重複キーが存在しません、このエントリがリストに追加され、前記詳細後
    addEntry(ハッシュ、キー、値、I);
     戻り NULL ; 
}

1.アレイの初期化(inflateTable)

プライベート ボイド inflateTable(INT toSize){
     // 配列のサイズは、2のn乗でなければならないことを保証します。
    // 例のように初期化:新しいHashMapの(20)、プロセスは、アレイ32の初期サイズである
    int型の容量= roundUpToPowerOf2(toSize);
     // 拡張閾値計算:容量* loadFactorの 
    閾値=(INT)Math.min(容量* loadFactorを。+ 1 MAXIMUM_CAPACITYが);
     // 初期化するアレイバー 
    表= 新しい新しいエントリー[容量]; 
    initHashSeedAsNeeded(容量); // 無視 
}

 

2.リストにノードを追加します(addEntry)

無効 addEntryを(intをハッシュ、Kキー、Vの値は、int型bucketIndexを){
     // 現在のHashMapのサイズが閾値を、新しい値に達した場合にアレイ位置に挿入される、その後膨張要素、有する
    IF((サイズ> =閾値)&&(ヌル!= 表は[bucketIndex])){
         // 拡張、後から導入する 
        リサイズ(2 *のtable.length);
         // 拡張を将来的には、ハッシュ再計算する 
        ハッシュを=(ヌル =キー)ハッシュ(!? )キー:0 ;
         // 新しい拡張インデックスの後に再計算 
        bucketIndex = indexFor(ハッシュ、table.length); 
    } 
    // 見下す
    createEntry(ハッシュ、キー、値、bucketIndexを); 
}
// これは、次いで++サイズ、実際には、リストのヘッダに新たな値が非常に簡単である
ボイド createEntry(INTハッシュ、鍵K、V値、int型bucketIndex)を{ 
    エントリ <K、V> E = ;表[bucketIndex] 
    表【bucketIndex] = 新しい新規エントリ<> ハッシュ、キー、値、E); 
    サイズ ++ ; 
}

3.拡張アレイ(リサイズ)

無効リサイズ(INT newCapacity){ 
    エントリー[] oldtable = ;表
     INT oldCapacity = oldTable.length;
     IF(oldCapacity == MAXIMUM_CAPACITY){ 
        閾値 = Integer.MAX_VALUEの;
         返す; 
    } 
    // 新しい配列 
    エントリー[] = NEWTABLE 新しい新しいエントリ【newCapacity];
     // 元の配列の値は、新しい、より大きなアレイに移行
    転送(NEWTABLE、initHashSeedAsNeeded(newCapacity));  = NEWTABLE; 
    閾値 =(INT)Math.min(newCapacity * loadFactor、MAXIMUM_CAPACITY + 1 )。
}

4.getプロセス分析

  計算されたハッシュ値のキー。
  対応する配列の添字を探す:ハッシュ・(長さ- 1) 。
  キーを見つけるのは等しくなるまでアレイ位置(または等しい==)Aのリストを横断します。

パブリックVのGET(オブジェクトキー){
     // そう長いテーブルトラバースリストとして[0]になります、[0]、キーがnullである前に、それがテーブルに置かれると述べ
    IF(キー==のヌルリターンgetForNullKey();
     //  
    エントリ<K、V> =エントリのgetEntry(KEY); 

    戻り ヌル ==エントリ?ヌル:entry.getValue(); 
}

getEntry(キー):

最終エントリ<K、V> のgetEntry(キーオブジェクト){
     IF(サイズ== 0 ){
         戻り NULL ; 
    } 

    int型ハッシュ=(キー==のヌル)0? ハッシュ(キー);
     //は、配列インデックスを決定し、そして先頭からリストのトラバース、それが見つかるまで
    ため(エントリ<K、V> E = 表[indexFor(ハッシュ、table.length)]; 
         E!= NULL ; 
         E = e.next){ 
        オブジェクトK; 
        IF(e.hashハッシュ&& == 
            ((K = e.key)== ||キー(キー!= nullの && key.equals(K))))
             リターンE; 
    } 
    戻り ヌル
}

他の質問は、を指すことができる、配列インデックスの(ハッシュ関数H&(長さ1)説明をハッシュマップ)があります。

https://blog.csdn.net/sd_csdn_scy/article/details/55510453

 

おすすめ

転載: www.cnblogs.com/zhishifenzi/p/11762465.html