HashMapの原則(a)の概念と基本的なアーキテクチャ

HashMapの<文字列、整数>地図データ=新しいHashMapの<>();

私たちは、ここからソースコードを入力して、徐々にHashMapを公開します

/ ** 
 *デフォルトの初期容量で空の<tt>のHashMap </ tt>を構築します
 *(16)とデフォルトの負荷係数(0.75)。
 * / 
公共のHashMap(){ 
    this.loadFactor = DEFAULT_LOAD_FACTOR。//他のすべてのフィールドがデフォルトと
}

私たちは、ビューの命名観点から、二つの変数loadFactorとDEFAULT_LOAD_FACTORが見つかりました:loadFactorにデフォルト値を割り当てるloadFactorパラメータを受け取っていないので。それが何を意味するのか、最終的にこれらの二つの変数は、他の変数が存在しませんか?

実際には、多くの変数とHashMapの中で定義された静的メンバ変数は、我々は見て

//静态变量
= 1 << 4静的最終int型DEFAULT_INITIAL_CAPACITY。//別名16 

= 1 << 30静的最終int型MAXIMUM_CAPACITY。

静的最終フロートDEFAULT_LOAD_FACTOR = 0.75F。

静的最終INT TREEIFY_THRESHOLD = 8。

静的最終INT UNTREEIFY_THRESHOLD = 6。

静的最終int型MIN_TREEIFY_CAPACITY = 64。
//成员变量
過渡ノード<K、V> []テーブル。

一過性の設定<のMap.Entry <K、V >>のentrySet。

過渡int型のサイズ。

一過性のint modCount。

int型のしきい値。

最終フロートloadFactor。

6つの静的変数の合計を初期値に設定され、修正さ最終的なものであり、実際には、それらの役割を推測することができ、より適切な定数と呼ばれ、条件判定、等に関連するメンバ変数とメソッドの値をデフォルト設定であります。

これらに加えて、6つのメンバ変数、メンバ変数の合計は、能力の重要な概念があり、私たちは主にテーブルについて話、のentrySet、容量、サイズ、しきい値、loadFactorは、我々は簡単に、彼らが何をすべきかを説明し、私たち。

1.テーブル変数

HashMapを格納するためのデータ構造の基礎となる変数テーブルハッシュマップは、ノードは、静的内部クラス、アレイ及びリストの組み合わせの複合構造体であるキー値はい、ノードアレイに加え、我々は、ノードクラスを見:

静的クラスノード<K、V>実装のMap.Entry <K、V> { 
    最終INTハッシュ。
    最後のKキー。
    V値。
    次のノード<K、V>。

    ノード(INTハッシュ、Kキー、Vの値は、ノード<K、V>次){ 
        this.hash =ハッシュ。
        this.key =キー。
        this.value =値。
        this.next =次回。
    } 

    公共の最終的なKのgetKey(){リターンキー。} 
    公共の最終的なVのgetValue(){戻り値。} 
    公共の最終的な文字列のtoString(){キー+ "=" +値を返します。} 

    パブリック最終int型のハッシュコード(){ 
        Objects.hashCode(キー)^ Objects.hashCode(値)を返します。
    } 

    公共の最終的なVのsetValue(V newValueに){
        V OLDVALUE =値。
        値= newValueに。
        OLDVALUEを返します。
    } 

    公共の最終的なブール等しい(オブジェクトo){ 
        IF(O ==本)
            trueを返します。
        (のMap.Entryのinstanceof O){もし
            <?、> OのMap.Entry E =(<?>のMap.Entry)。
            もし(Objects.equals(キー、e.getKey())&& 
                Objects.equals(値、e.getValue()))
                trueを返します。
        } 
        falseを返します。
    } 
}

メタファーを行うための機会の面では、あなたはチケットID番号を購入する(されるキー、)ハッシュアルゴリズム(によって生成されたハッシュ値)は、マシンを得るために航空座席数の値に相当し、独自の性質は(ある)、あなたは次の次の人へのシートは、ノード(ある(要員とID番号、座席の座席番号を含む)は、シート全体である;)テーブルのテーブル構築多くは、ノード[]テーブルを構成し、このフライトの作業。

なぜリンクリストデータ構造配列と組み合わせて使用​​しますか?

そして、我々は、配列が簡単、比較的困難挿入、削除を扱う長所と短所、継続的なストレージアレイ、独自のリストを持っていることを知って、リストが離散的に保存され、比較的困難アドレッシング、および容易に挿入操作を削除し、2つのHashMapの組み合わせ種のデータ構造は、後のセクションを説明TreeMapのそれぞれの利点を保持し、自分の欠点を作る、当然のことながら、リストの長さが長すぎる、JDK8に赤、黒の木に変換し、赤、黒の木。

次のように図HashMapの構成は次のとおりです。

この構造を説明するには?

発券システムがよりユーザーフレンドリーで、チェックインの操作をキャンセルし、チケットが通信旅を容易にするため、年齢によって区別されている場合か説明する機会を例に、その後、20歳は、グループ内の6人の合計に分けました図20A〜20Fは、20〜30歳群21A〜21Fに6つの個体に分け、30〜40歳、コンポーネント22Aに6つの個体に分け〜22F、40〜50年6個体群23Aの合計〜 23F。

私たちは20代の妹を探しているならその後、我々は21の行を見つけるのは簡単であることを知って、スタート21Aから見下ろして、あなたはすぐに見つけることができるはずです。

観点からデータの後に、年齢によってグループ化(ハッシュアルゴリズムにより得られたハッシュ値と、異なるハッシュ値の年齢、同じ年齢の同じハッシュ値)、各人物の年齢に座席に座るします配列表は、次の人が来て、自分自身の配列、および最初の人に、次のポイントで、ノルウェーに入った最初の人になります。

2.のentrySet変数

変数が作成されていないを確実にするために数回繰り返すことができるように定義のentrySet変数のentrySetエンティティは、、、のMap.Entry <K、V>はインターフェースのMap.Entryのコレクションである、Nodeクラスは、インターフェイスを実装するので、プロセスはのentrySetが必要データ操作は、ノードエンティティのHashMapのです。

公共セット<のMap.Entry <K、V >>のentrySet(){ 
    設定<のMap.Entry <K、V >> ES。
    リターン(ES =のentrySet)== nullの?(のentrySet =新しいのentrySet()):ES; 
}

3.容量

容量は、メンバ変数ではなく、よく理解、その能力を意味し、この概念に使用されますHashMapの多くの場所で、前回の記事で言及した2つの定数が関連しています

/ ** 
 *デフォルトの初期容量- (2の累乗でなければならない)は、2つでなければなりませんの電源。
 * 16デフォルトの容量、例えば:ノーマルシート、に対応する平面上の人の数
 * / 
。静的INT最終DEFAULT_INITIAL_CAPACITY 1 = 4 <<; 16 // AKA 
/ ** 
 最大の*能力、Aは、暗黙的に指定された値COMMUNICAITIONSの領域にある場合に使用
 *コンストラクタと引数のいずれかによる。
 *の電力は、2 <= 30 1 <<(2なければならないしなければなりません電源、および1073741824の最大容量を超えることはできません)。
 たとえば、*を:そのような災害救援要員なるべく早く避難する人の数などの緊急事態での安全性を確保する場合に立ってできるようにするには、この時間()で、輸送することができる
 * / 
静的ファイナルINT MAXIMUM_CAPACITY = 1 << 30。

一方のHashMapも膨張機構を有し、2のべき乗の容量の規則は、その容量は、この容量のルールを実現する方法、... 16、32とすることができますか?

/ ** 
 *指定されたターゲット容量用の2つのサイズの電源を返します。
 * / 
静的最終INT tableSizeFor(INTキャップ){ 
    int型のn =キャップ- 1。
    N | = N >>> 1。
    N | = N >>> 2。
    N | = N >>> 4。
    N | = N >>> 8。
    N | = N >>> 16。
    リターン(n <0の)?1:(N> = MAXIMUM_CAPACITY)?MAXIMUM_CAPACITY:N + 1。
}

即ち、2の最も近いパワープロセスの能力を見つけるために渡され、

キャップ= 2,2返します。

キャップ= 3、4返します。

キャップ= 9、16を返します。

...

キャップ自体キャップを差し引いた2の電源、4でない場合、最終的な結果の下を通過するときには、2回の転送であろうあるので、我々は、自分の数、第1キャップ-1運転に値を渡すことができ。

行ずつは、私たちが計算します。tableSizeFor(11)を、最終規則の結果に応じて16を取得する必要があります

//ステップ:N = 10、バイナリ00001010に変換される
。INT = N-CAP - 1; 
//工程:N-1右に、高いビット0(小数点以下10:5、バイナリ:00000101)、およびそしてnか、または操作(1 0~0と、1)、次いでN(小数10:15、バイナリ:00001111)に割り当てられた
N | N >>> = 1; 
//第三段階:N右15、バイナリ:00001111 N(10進に割り当てられ、次いで、及び(0にして、1対1)のn-OR演算を行い、2,0の上位ビット(00000011進:10:3​​、バイナリ) )
N | N = 2 >>>; 
//ステップ4:4 N右、高いビット0(小数点以下10:0、バイナリ:00000000)、およびN-OR演算(1:1、とを行います15、バイナリ:0 0)、次いで(10進nに割り当てられている00001111)
N - | = N - >>> 4; 
//ステップ5:N-8右、高いビット0(小数点以下10:0バイナリ:00000000)、および0〜0で)、N-OR演算(1 1に行い、その後、N(小数10に割り当てられた:15、バイナリ:00001111)
N | = N >>> 8; 
// 0 0と1、およびn OR演算を行う(1、ステップ6:N 16ビット右に、高いビット0(00000000 10進:0、バイナリ)、そしてnに割り当てられている(10進:15、バイナリ:00001111)
N- | N - >>> = 16; 
//ステップ7:リターン1 + 15 = 16; 
リターン(N- <0?)1:(N-。> ?= MAXIMUM_CAPACITY)MAXIMUM_CAPACITY:N + 1。

その結果、予想通り、非常に高速なハードウェアアルゴリズムああ、ヽ(ー_持つ)テクノは、読み取ることができますが、デザインは出てきません。

4.サイズの変数

putValueメソッド()メソッドおよびremoveNode()メソッドを呼び出すときにサイズ変数はマップ内のキーと値のペアの数を記録し、それを変更するようになります、と容量がどのようなことができますを区別します。

5.しきい値変数と変数loadFactor

それは、拡張に関連して臨界値、HashMapを超えると、クリティカルのしきい値は、定義により、あなたが何かをする必要があり、しきい値、および臨界値のHashMapで「閾値=容量* loadFactor」として働いていました。

負荷率にloadFactorがデフォルト値、ハッシュマップの全範囲を測定するために使用されるDEFAULT_LOAD_FACTOR、すなわち0.75F、コンストラクタによって調整パラメータを渡すことができる(非常に合理的0.75Fを、基本的に誰もそれを調整しないであろう)、よく理解例えば:

100の試験問題、親が負荷率が0.75,75分で、あなたのお気に入りのコンピュータを買う与え、あなたをテストするだけで75分を必要とする臨界値であり、数年後の場合は200ポイントにスコアの質問、この時間はあなたの好きなコンピュータを得るために150ポイントをテストする必要があります。

概要

その基礎となるデータ構造はソース、テーブルデータの観点から分析されている間、この記事では、ハッシュマップの主な概念のいくつかを説明し、複合構造体は、HashMapの容量容量と、キーと値のペアの記録された数のリンクされたリスト、大きさ、ルールの容量は、2の累乗であるこのようloadFactorにロードされ、しきい値が膨張します超えた閾値臨界値の程度の完全な尺度。

おすすめ

転載: www.linuxidc.com/Linux/2019-08/160021.htm