HashMap原理の詳細
4779 ワード
hashMapは何ですか
HashMapはJavaでよく使われているキーパッドのデータ構造で、スレッドが安全ではないので、nullキーの値を保存できます。これらはよく使われています。
一、原理を実現する
HashMapは配列ハッシュ+チェーン表を用いてキーペアを格納し、キーペアのオブジェクトは次のように実現される。
一、putメソッドは、キーのペアに書き込みます。
addEntryの実現
コード:
二、get方法
三、注意すべき点は、hash Mapの原理により、主な格納はhash値の計算に依存するので、Stringを選択すると、IntegerなどをキーにするとhashMapの効率が向上します。StringなどのオブジェクトがMapに入れば変化しないので、hash値も変わらず、取得対象の速度が大幅に向上します。 HashMapのサイズが負荷係数定義の容量を超えている場合、HashMapは元の2倍のbucket配列を作成し、元のオブジェクトを新しい配列に入れて、hashMapの容量を拡大する。(負荷係数初期0.75) は、複数のスレッドで同時にHashMapのサイズが小さいことを発見し、サイズの調整を試み、条件競争を引き起こす。 は、Java 8において、hashと同じkeyの数が8より大きい場合、チェーンの代わりにバランスツリーを使用する。 HashMapはなぜスレッドが不安定ですか?上記のように、二つのスレッドが同時にHashMapの拡張を試みる時、一つのチェーンをリング状のチェーンテーブルに形成するかもしれません。すべてのnextは空ではなく、デッドサイクル に入ります。は、2つのスレッドが同時にputされると、1つのスレッドデータが失われる可能性がある 。
HashMapはJavaでよく使われているキーパッドのデータ構造で、スレッドが安全ではないので、nullキーの値を保存できます。これらはよく使われています。
一、原理を実現する
HashMapは配列ハッシュ+チェーン表を用いてキーペアを格納し、キーペアのオブジェクトは次のように実現される。
static class Entry<K,V> implements Map.Entry<K,V> {
final K key;
V value;
Entry next;
final int hash;
……
}
一つのEntryの配列テーブルを通して複数のオブジェクトの保存を実現し、ハッシュ値とキー値を使って挿入と検索の衝突を解決しました。一、putメソッドは、キーのペアに書き込みます。
public V put(K key, V value){
// key null, putForNullKey null
if (key == null){
return putForNullKey(value);
}
// key keyCode Hash
int hash = hash(key.hashCode());
// hash table
int i = indexFor(hash, table.length);
// i Entry null, key Entry
for (Entry e = tablei; e != null; e = e.next) {
Object k;
// key hash Entry
if (e.hash == hash && ((k = e.key) == key|| key.equals(k)){
//key value ,
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
// i Entry null key hash key , Entry
modCount++;
// key、value i
addEntry(hash, key, value, i);
return null;
}
put方法でhash衝突を解決する方法ははっきりしています。つまり、2つのentryのhash値が同じであるとき、key値が同じかどうかを判断する必要があります。keyとhashは同じでなければ、修正できません。addEntryの実現
コード:
void addEntry(int hash, K key, V value, int bucketIndex)
{
// bucketIndex Entry
Entry e = tablebucketIndex;
tablebucketIndex = new Entry(hash, key, value, e);
// Map key-value
if (size++ >= threshold)
resize(2 table.length);
}
新しいEntryを作成するには、テーブルのbucketIndexに要素があれば、作成時にイベントのnextを元の記憶要素に設定する必要があります。二、get方法
public V get(Object key)
{
// key null, getForNullKey null value
if (key == null)
return getForNullKey();
// key hashCode hash
int hash = hash(key.hashCode());
// table ,
for (Entry e = table[indexFor(hash, table.length)];
e != null;
// Entry
e = e.next)
{
Object k;
// Entry key hash key
if (e.hash == hash && ((k = e.key) == key
|| key.equals(k)))
return e.value;
}
return null;
}
によって実現される原理はgetと同じである。三、注意すべき点