千鋒教育Java入門全套視頻教程(java核心技術(shù),適合java零基礎(chǔ),Java

HashMap源碼分析
transient Node<K,V>[] table;//HashMap的底層實現(xiàn)
final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
????????boolean evict) {
??Node<K,V>[] tab; //臨時數(shù)組???存放所有hash桶中的頭節(jié)點
??Node<K,V> p; //臨時節(jié)點 某一個桶的頭節(jié)點(一個單向鏈表)
??int n, i;
??if ((tab = table) == null || (n = tab.length) == 0)//先賦值后判斷
????n = (tab = resize()).length;//第一次初始化容量(16),之后為擴容
??if ((p = tab[i = (n - 1) & hash]) == null)
????//取hash后log n 位決定數(shù)值放在哪個位置
????//為了防止漏桶,n(容量)必須為2的多次方
????//無參,默認為16,擴容是翻倍
????//帶參時,通過tableSizeFor方法獲取設(shè)定容量最接近的大于容量的2的多次方,擴容是翻倍
????tab[i] = newNode(hash, key, value, null);//如果這個桶里一個元素都沒有,則直接放入元素
??else {
????//指向的hash桶里有東西時
????Node<K,V> e;?
????K k;
????if (p.hash == hash &&//如果加入的key與第一個是一樣的
??????((k = p.key) == key || (key != null && key.equals(k))))
??????e = p;//用e暫存相同的節(jié)點
????else if (p instanceof TreeNode)//如果頭結(jié)點是一個樹節(jié)點
??????e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
????//調(diào)用紅黑樹的方法往樹里添加節(jié)點,如果沒有重復(fù),返回null
????//如果有返回這個節(jié)點并用e暫存?
????else {//如果是鏈表
??????for (int binCount = 0; ; ++binCount) {
????????if ((e = p.next) == null) {//判斷p的下一節(jié)點是否為空
??????????p.next = newNode(hash, key, value, null);//如為空,將數(shù)值放到此位置
??????????if (binCount >= TREEIFY_THRESHOLD - 1) // 是否樹化
????????????treeifyBin(tab, hash);
??????????break;
????????}
????????if (e.hash == hash &&//找到相同節(jié)點
??????????((k = e.key) == key || (key != null && key.equals(k))))
??????????break;
????????p = e;
??????}
????}
????if (e != null) { // 有相同節(jié)點時返回被覆蓋的值
??????V oldValue = e.value;
??????if (!onlyIfAbsent || oldValue == null)
????????e.value = value;
??????afterNodeAccess(e);
??????return oldValue;
????}
??}
??++modCount;
??if (++size > threshold)//到達閾值后擴容
????resize();
??afterNodeInsertion(evict);
??return null;
}