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++;
}
/**key、value 都不允許為空 key不允許為空 因為hashcode取的是key 該物件的hashcode()** **擴容
** 觸發 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;) }}
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 ...