hashmap的loadfactor為什麼是0.75?
主要涉及到泊松分布的概念,猝!!!
乙個bucket空和非空的概率為0.5,通過牛頓二項式等數學計算,得到這個loadfactor的值為log(2),約等於0.693. 同回答者所說,可能小於0.75 大於等於log(2)的factor都能提供更好的效能,0.75這個數說不定是 pulled out of a hat。
public v put
(k key, v value)
static
final
inthash
(object key)
final v putval
(int hash, k key, v value,
boolean onlyifabsent,
boolean evict)
if(e.hash == hash &&
((k = e.key)
== key ||
(key != null && key.
equals
(k))))
break
; p = e;}}
//更新key的值
if(e != null)
}//記錄修改次數
++modcount;
//超過限制容量,擴容if(
++size > threshold)
resize()
;//空操作
afternodeinsertion
(evict)
;return null;
}
public v remove
(object key)
final node
removenode
(int hash, object key, object value,
boolean matchvalue,
boolean movable)
p = e;
}while
((e = e.next)
!= null);}
}if(node != null &&
(!matchvalue ||
(v = node.value)
== value ||
(value != null && value.
equals
(v))))
}return null;
}
@override
public v replace
(k key, v value)
return null;
}final node
getnode
(int hash, object key)
while
((e = e.next)
!= null);}
}return null;
}
public v get
(object key)
final node
resize()
elseif(
(newcap = oldcap <<1)
< maximum_capacity &&
oldcap >= default_initial_capacity)
//如果擴容後的大小newthr = oldthr <<1;
// double threshold
}else
if(oldthr >0)
// initial capacity was placed in threshold
newcap = oldthr;
else
if(newthr ==0)
threshold = newthr;
@suppresswarnings()
//臨時儲存擴容後的值
node
newtab =
(node
)new
node
[newcap]
;//在整個擴容節點,table為空
table = newtab;
//以下執行擴容操作
if(oldtab != null)
else
}while
((e = next)
!= null)
;//為什麼擴容後,相同的在原位置儲存,而不同的則當前索引+之前原位置索引儲存?
//因為這裡的擴容都是擴容一倍,也就是01000擴容後變成10000
// 當e.hash & oldcap == 0,說明hash《當前容量,也就是落在0~1000範圍內,哪怕擴容後,進行&操作也是一樣的索引值
//!=0,則說明第一e.hash落在0~1000範圍內,第二包含1000這個位置.而1000是之前擴容前的容量,所以最新的位址為擴容前容量+當前索引
//原位置儲存
if(lotail != null)
//儲存索引在擴容的那部分
if(hitail != null)}}
}}return newtab;
}
final node
nextnode()
while
(index < t.length &&
(next = t[index++])
== null);}
return e;
}
jdk8中,改變了底層資料結構,為線性表+鍊錶+紅黑樹
產生hash值碰撞後,用鍊錶儲存碰撞的值
什麼時候採用紅黑樹?
當桶裡面存的鍊錶個數》8,同時陣列長度》64,的時候採用紅黑樹
預設載入因子0.75
預設容量16,載入擴容的大小12
key一樣時,覆蓋舊的value
可以存null,索引0
為什麼每次擴容後,是2的冪次方?
是因為在使用2的冪的數字的時候,length-1的值是所有二進位制位全為1,這種情況下,index的結果等同於hashcode後幾位的值。
只要輸入的hashcode本身分布均勻,hash演算法的結果就是均勻的。
這是為了實現均勻分布。
為什麼擴容後,相同的在原位置儲存,而不同的則當前索引+之前原位置索引儲存?
//因為這裡的擴容都是擴容一倍,也就是01000擴容後變成10000
// 當e.hash & oldcap == 0,說明hash《當前容量,也就是落在0~1000範圍內,哪怕擴容後,進行&操作也是一樣的索引值
//!=0,則說明第一e.hash落在0~1000範圍內,第二包含1000這個位置.而1000是之前擴容前的容量,所以最新的位址為擴容前容量+當前索引
//原位置儲存
if(lotail != null)
//儲存索引在擴容的那部分
if(hitail != null)
為啥用尾插法?
jdk7因為頭插法存在環形問題
而jdk8,使用尾插,在擴容時會保持鍊錶元素原本的順序,就不會出現鍊錶成環的問題了
為什麼執行緒不安全?
在jdk1.7中,在多執行緒環境下,擴容時會造成環形鏈或資料丟失。
在jdk1.8中,在多執行緒環境下,會發生資料覆蓋的情況。
原始碼解析 JDK原始碼之LinkedHashMap
linkedhashmap原始碼,基於 jdk1.6.43 他繼承了hashmap,並且實現了插入和訪問的有序功能 public class linkedhashmapextends hashmapimplements map 其也有乙個entry內部類,繼承了 hashmap 的entry 內部類...
JDk原始碼解析之四 Vector原始碼解析
具體的三個屬性 解釋看圖中注釋。vector沒有採取arraylist臨界值擴容的辦法,而是每次不夠的時候,直接根據capacity的值來增加。具體怎麼增加後面會說。vector的構造方法如下。簡單粗暴,如果呼叫無參建構函式,直接就將初始容量設定成了10,最終在右側的構造方法裡,將陣列的長度設定為1...
JDK原始碼解析 ThreadLocal
說明 本文是jdk 1.8版本 1.簡介 threadlocal 又叫做執行緒本地變數,也被稱為執行緒本地儲存。threadlocal 為 變數 在每乙個執行緒中建立 乙個 副本 不是原來變數的引用 每乙個執行緒都會獨自擁有變數副本,而不會相互影響。2.實現方式 1 set 方法,因為執行緒thre...