HashTable原理與原始碼分析

2022-03-15 16:16:35 字數 3907 閱讀 9480

hashtable內部儲存結構為陣列+單向鍊錶的形式儲存資料,即定義的entry,?> table 變數

使用entry陣列儲存資料 (entry 單向鍊錶)

private

transient entry,?> table;

//已經儲存在table 的 entry 個數

private

transient

intcount;

/****

* entry陣列擴容閾值(count) count>=threshold 時擴容 entry陣列會進行擴容

* 建議不要設定超過1 更要不設定太大,導致鍊錶長度過長 會導致查詢很慢

* 比如 hashtble initialcapacity =5 loadfactor=0.75 則計算 threshold =3

* when count >=3 時 table開始擴容(具體如何擴容的看擴容**)

* **

*/private

intthreshold;

//負載因子 用於計算 threshold

private

float

loadfactor;

//記錄修改次數

private

transient

int modcount = 0;

//table陣列的最大長度

private

static

final

int max_array_size = integer.max_value - 8;

/**

* hashtable bucket collision list entry

*單向鍊錶 */

private

static

class entryimplements map.entry

@suppresswarnings("unchecked")

protected

object clone()

opspublic

k getkey()

public

v getvalue()

public

v setvalue(v value)

public

boolean

equals(object o)

public

inthashcode()

public

string tostring()

}

/**

* * 初始化hashtable 指定初始化容量(initialcapacity),負載因子(loadfactor)

*hashtable初始化核心**

* **/public hashtable(int initialcapacity, float

loadfactor)

/*** * 初始化hashtable 指定初始化容量(initialcapacity)

* 預設負載因子大小為0.75

* **

*/public hashtable(int

initialcapacity)

/***

* 預設初始化 entry陣列 大小為 11

* loadfactor =0.75

***/public

hashtable()

/***

* *

***/public hashtable(map extends k, ? extends v>t)

/**

* **新增元素 key value

** 注意:put方法是加鎖的 這就是 hashtable 為啥是執行緒安全的原因 阻塞的

** key、value 均不能為空

****/public

synchronized

v put(k key, v value)

//makes sure the key is not already in the hashtable.

entry,?> tab =table;

//hashcode取的是key的hashcode key不能為空

int hash =key.hashcode();

//根據hashcode & long最大值雜湊 再對 陣列長度取模獲取到所要插入的陣列下標

int index = (hash & 0x7fffffff) %tab.length;

@suppresswarnings("unchecked")

//檢視陣列該下標下是否存在元素 如存在便利 value(新)覆蓋key相同的值

entryentry = (entry)tab[index];

for(; entry != null ; entry =entry.next)

}//儲存

addentry(hash, key, value, index);

return

null;}

/***

*儲存***/

private

void addentry(int hash, k key, v value, int

index)

//creates the new entry.

@suppresswarnings("unchecked")

//查詢陣列原有的entry鍊錶

entrye = (entry) tab[index];

//將entry儲存 並將entry.next 指向原來的entry鍊錶

tab[index] = new entry<>(hash, key, value, e);

//陣列長度+1

count++;

}

/**

** **擴容

** 觸發 count(已儲存的entry個數) >= threshold(閾值)

****/protected

void

rehash()

//新建乙個陣列長度為 oldcapacity*2+1 陣列

entry,?> newmap = new entry,?>[newcapacity];

modcount++;

//計算閾值

threshold = (int)math.min(newcapacity * loadfactor, max_array_size + 1);

table =newmap;

//將舊陣列中的entry 重新計算轉移到新陣列中

for (int i = oldcapacity ; i-- > 0;) }}

key、value 都不允許為空 key不允許為空 因為hashcode取的是key 該物件的hashcode()

hashtable 預設構造方法 容量初始化為 11 負載因子為 0.75   

若使用帶負載因子的構造方法建立hashtable 請不要講負載因子設定過大 比如 初始化容量設為 1 負載因子設為1000 這樣會導致查詢很慢

hashtable是陣列+單項鍊表entry的結構來儲存資料

陣列table最大長度為 integer.max - 8;

擴容條件 count(hashtbale 儲存鍊錶的個數) >= threshold(閾值 計算方法 table.length * loadfactor)

執行緒安全

HashTable原理和原始碼分析

hashtable的特性 hashtable 跟hashmap 最大區別是hashmap具備執行緒安全性,所有的方法都是安全的 hashtable不支援null值和null鍵 hashtable結構同hashmap產不多 陣列 鍊錶,而且沒有紅黑樹,相比更簡單了 擴容 原始碼解析 引數 privat...

原始碼剖析 Hashtable 原始碼剖析

hashtable同樣是基於雜湊表實現的,同樣每個元素都是key value對,其內部也是通過單鏈表解決衝突問題,容量不足 超過了閾值 時,同樣會自動增長。hashtable也是jdk1.0引入的類,是執行緒安全的,能用於多執行緒環境中。hashtable同樣實現了serializable介面,它支...

Hashtable原始碼詳解

成員變數private transient entry table 儲存鍊錶的陣列 private transient int count private int threshold private float loadfactor private transient int modcount 0 ...