HashMap
知識(shí)點(diǎn)1 :怎么求的Hash遂赠,通過對(duì)象的Hashcode值 高16位保持不變 低16位與高16位異或求值 得到Hash值
知識(shí)點(diǎn)2 : Hash碰撞 擁有相同的Hash值產(chǎn)生碰撞 新版HashMap會(huì)把數(shù)據(jù)放在此下標(biāo)的鏈表里 放在表尾 鏈表過長(zhǎng)會(huì)采用紅黑樹
知識(shí)點(diǎn)3 : Index的計(jì)算 Hash & (n-1)n為當(dāng)前bucket的size bucket是一個(gè)數(shù)組
知識(shí)點(diǎn)4 : bucket擴(kuò)容時(shí) 重新計(jì)算 Index = Hash &(n-1)n為新的數(shù)組size 值還是會(huì)均勻的分布在bucket數(shù)組當(dāng)中
知識(shí)點(diǎn)5 : key value可以為null
知識(shí)點(diǎn)6: :reHash時(shí) 判斷新增的位是否為0 0就不變 , 1 移動(dòng)兩位
知識(shí)點(diǎn)7 :HashMap 當(dāng)自定義對(duì)象時(shí)需要重寫equals方法為什么需要重寫hashcode
苛谷?因?yàn)椴煌膆ashcode可能會(huì)返回一樣的index下標(biāo) 梯捕,然后判斷equals(默認(rèn)地址比較)的時(shí)候掰派,可能會(huì)相同造成覆蓋問題颖榜,這種情況符合項(xiàng)目的話,其實(shí)是可以不重寫的拍摇,但是大多數(shù)情況下需要重寫亮钦。
衍生知識(shí)點(diǎn) : 如何保證線程安全,Collections.synchronizedMap()方法來得到一個(gè)同步的HashMap充活,HashTable蜂莉,ConcurrentHashMap,性能:ConcurrentHashMap > SynchronizedMap > Hashtable混卵。
jdk1.8 采用CAS + synchronized 正常情況下hash不沖突時(shí) put 采用CAS插入映穗,沖突時(shí)會(huì)同步鎖住。擴(kuò)容操作時(shí)的線程安全幕随,擴(kuò)容時(shí)也允許查找數(shù)據(jù)蚁滋。
get 基本和HashMap類似。
ArrayList
知識(shí)點(diǎn)1: 結(jié)構(gòu)比較簡(jiǎn)單赘淮,大于現(xiàn)有數(shù)組長(zhǎng)度 擴(kuò)容 實(shí)現(xiàn)可變size的動(dòng)態(tài)數(shù)組
知識(shí)點(diǎn)2: 核心是擴(kuò)容機(jī)制辕录,默認(rèn)最大容量10,當(dāng)達(dá)到這個(gè)數(shù)時(shí)會(huì)擴(kuò)大到1.5倍梢卸。
LinkedList
知識(shí)點(diǎn)1 : 雙向鏈表實(shí)現(xiàn)走诞。查找慢
TreeMap
知識(shí)點(diǎn)1: 紅黑樹 樹的中序遍歷保證有序
LinkedHashMap
知識(shí)點(diǎn)1: 繼承了HashMap 依靠雙向鏈表實(shí)現(xiàn)順序訪問
知識(shí)點(diǎn)2: 有兩種模式:順序模式和訪問模式,順序模式按照插入順序輸出蛤高,訪問模式按照訪問的時(shí)間蚣旱,訪問中間的元素會(huì)放到雙向鏈表的最后碑幅。
訪問模式代碼
void afterNodeAccess(Node<K,V> e) { // move node to last
LinkedHashMapEntry<K,V> last;
if (accessOrder && (last = tail) != e) {
LinkedHashMapEntry<K,V> p =
(LinkedHashMapEntry<K,V>)e, b = p.before, a = p.after;
p.after = null;
if (b == null)
head = a;
else
b.after = a;
if (a != null)
a.before = b;
else
last = b;
if (last == null)
head = p;
else {
p.before = last;
last.after = p;
}
tail = p;
++modCount;
}
}
知識(shí)點(diǎn)3: put的時(shí)候會(huì)調(diào)用linkNodeLast
加到最后
private void linkNodeLast(LinkedHashMapEntry<K,V> p) {
LinkedHashMapEntry<K,V> last = tail;
tail = p;
if (last == null)
head = p;
else {
p.before = last;
last.after = p;
}
}