HashMap.put

まず、物理的な解体の解体2つだけ(順次格納されている解体)(チェーン店の解体)に格納されたデータを理解する必要があり、
(としてメモリにマップする抽象図の論理構造から等スタック、キュー、ツリー、)

それでは、私たちは、デザインのHashMapののput()メソッドを達成するために自分自身を想像したら?

ときに私のデータ私たちはアドオン(内部リストコレクションにこのデータを入金する必要があるとき、私たちは)、このデータを検討するかどうか
(ループを通って、このデータによると、第二の前に格納されたデータが存在しているかどうかを判断の中で私たちのリストの到来しますこの機能を実現するためにそれを比較するための便利では)問題ないようですか?
このアプローチは、データの量が増加に比例した回数を何回我々サイクルデータO(N)アルゴリズムであり、時間がかかります

アルゴリズム- O(1)、O( N)、O(LOGN)、O(nlogn)
(1)、O(N 2 Oに使用されるアルゴリズムの複雑記述 )、O(LOGN)、O(nlogn)を示し、対応するアルゴリズムそのアルゴリズムの時間計算量、空間と時間の複雑さが表現されています。唯一、それはまた、宇宙の複雑さのために使用されている時間の複雑さを表すために使用されていません。
アルゴリズムの時間がかかる/消費データ空間増分の関係を示す関数の背後Oブラケット。ここで、Nは、入力されたデータの量を表します。
時間計算量はO(N)であるような、データの量が増加する数回の消費、数倍に増加さ表します。このような一般的なトラバースアルゴリズムとして。
別の例では、O(n個の時間複雑である2)、データが増加n回、n回の量の二乗を示し、時間のかかる時間の線形複雑度よりも高い、増加しました。例えば、バブルソートのために、典型的なO(nはスキャンN×N倍2)アルゴリズムの、数Nソート必要で。
データが倍増加LOGNを消費し、N倍に増加された別の例示O(LOGN)、(ログベース2は、唯一増加消費8倍、データが増加すると、例えば、256倍、こちらそれは)線形時間複雑さよりもさらに低くなっています。
バイナリサーチは、すべての半分はちょうどターゲットを見つけるために8を見つける必要がある256人のデータルックスの可能性を排除一度検索し、O(LOGN)アルゴリズムです。
O(nlogn)同様、logN個がNで乗算され、データが増加すると256倍、* 8 = 256加工が2048倍に増加しました。この広場の上の線形複雑度より低いです。マージソートO(nlogn)時間複雑です。
関わらず、入力データの、時間のかかる/スペース消費と入力データのサイズを何もしない最小の時間と空間の複雑さはO(1)は、何度も、時間のかかる/スペース消費量が同じで増加します。ハッシュアルゴリズムは、典型的なO(1)である
(言葉の抵触に関係なく)にかかわらず、スケールは、あなたが計算後の目標を見つけることができますどのくらいのデータの時間複雑さ、

しかし、その後、我々はO(N)を容易にする時間アルゴリズムを通過し、それは大量のデータを要する場合には、この問題を解決する方法は、現時点では予測不可能になりますか?

我々はO(1)時間アルゴリズムの両方を使用したい場合がハッシュアルゴリズム、私が行った各オブジェクトの参照データ型の彼のハッシュコードを計算したハッシュ値は、それを取得し、対応するインデックスへのインデックスのインデックス値に対応するデータを検索します我々は関係なく、私たちが必要なものの価値を見つけるために時間のかかる必要性だけを変更することはありません何回データの量を増加させないように、場所。

私たちは大丈夫、問題が何であるかを見ていなかった大量のデータの場合にはこの方法を使用するが、データよりも小さい場合は、スペースの無駄のために、どのようにそれを改善するために、場合?

私たちは、12以上の私たちの初期容量は、我々はスペースの大幅な節約になり、その後、インデックスは、我々はリストを採用し、複数の値を格納するかどうかを配列のインデックスにより、この値より対応の値を取得すると言う、オブジェクトの値に%をハッシュコードできるかどうか我々は再びO(n)で同一の値かどうかを決定するためにアルゴリズム等しいによる配向()メソッドを促進する追加の時間の形で格納することができ
、この点では、我々はリスト構造といくつかの初期値を設定してもよいHashMapの構成方法でを導入します以下を参照してください。

  • InitialCapacityの値:初期容量。これは、その容量のHashMapの初期のコレクションを指します。これは、コンストラクタで指定することができます。指定しない場合、デフォルトでは16の総容量です。初期容量が2の累乗でなければならないことに注意してください。
  • loadFactor:負荷率。負荷率が一定値に達すると、HashMapのはハッシュマップ(現在の容量/総容量)と呼ばれる
    拡張を実現します。負荷率がまた、コンストラクタで指定することができ、デフォルト値は0.75です。例えば、HashMapの初期容量が16であると仮定し
    、拡張閾値は0.75 * 16 = 12です。言い換えれば、値は、HashMapのは、最初の拡張を実行します13日になるだろう。
  • しきい値:拡張しきい値。すなわち、拡張閾値* = HashMapの負荷率の合計容量。電流容量がHashMapの拡張以上である場合、拡張閾値を実行するであろう。HashMapのの二倍現在の総容量の容量の拡大。例えば、ハッシュマップ16の合計電流容量は、次いで、膨張後32でした。
  • テーブル:項目配列。我々は、すべてのエントリを達成するために、この媒体を介してある店のキー/値の内部HashMapを知っています。テーブルエントリの配列です。
    ここに画像を挿入説明
    単純な、プラス下地リスト構造体を達成するために配列の配列は、ハッシュマップのHashMapであります
  • リストがない場合、インデックス(次ヌルに現在のエントリポイント)に対応する位置は、ルックアップに追加するより速く、他の操作のみアドレス値に一度です。
  • 対応する位置には、複雑さのリストを持っている必要がある場合は、新しいカバーのために存在する横断、O(N)倍である。そうでなければそれはまだすべての利便性は、それがパフォーマンスの内部HashMapの用語を表示されたら、リストを比較等しい見つける必要がありますあまり良いパフォーマンスがされます
//这是一个神奇的函数,用了很多的异或,移位等运算,对key的hashcode进一步进行计算以及二进制位的调整等来保证最终获取的存储位置尽量分布均匀 尽可能的减少Hash冲突 位运算代替模运算直接二进制运算不用转换成十进制
final int hash(Object k) {
        int h = hashSeed;
        if (0 != h && k instanceof String) {
            return sun.misc.Hashing.stringHash32((String) k);
        }

        h ^= k.hashCode();

        h ^= (h >>> 20) ^ (h >>> 12);
        return h ^ (h >>> 7) ^ (h >>> 4);
    }

Javaの1.8に、8よりもリストの長さは、リストは、赤黒木に変換される場合、画分2は、方法を見つけることです

ハッシュ衝突が発生した場合、Javaの1.7は、リストの先頭に挿入され、およびJava 1.8は、リストの末尾に挿入されます。

文字列は、ハッシュ衝突の不変の文字列オッズが比較的小さくされているので、なぜ彼らは常にキーとして文字列を使うのですか

公開された23元の記事 ウォンの賞賛2 ビュー925

おすすめ

転載: blog.csdn.net/metjoyful/article/details/104197008