HashMap源码阅读与理解

JDK1.8HashMap源码分析


HashMap几个对象:


HashMap源码阅读与理解

1、默认初始化大小。tips:为什么must be a power of two呢,因为在put元素的时候会进行(length-1)&hashcode操作,2的幂次方-1等于N个1!


HashMap源码阅读与理解HashMap源码阅读与理解

2、最大容量。


HashMap源码阅读与理解HashMap源码阅读与理解

3、加载因子。0.75*当前容量大小就是判断是否扩容的标准,而每次扩容都是<<1 也就是翻倍,也是为了2的幂次方。


HashMap源码阅读与理解

4、节点阈值。这个值就是当某个节点放入超过8个,也就是碰撞超过八次的某个节点就会被转换成红黑树。


HashMap源码阅读与理解HashMap源码阅读与理解

5、节点阈值。小于等于6个则化为原来的链表。


HashMap源码阅读与理解

6、节点阈值。大于64个才会生成红黑树。


HashMap源码阅读与理解HashMap源码阅读与理解

7、Node<K,V>对象存放bean


HashMap源码阅读与理解HashMap源码阅读与理解

8、table bean存放容器(可以理解为hashMap容器)


HashMap源码阅读与理解HashMap源码阅读与理解

9、Node<K,V> 属性值,hash值,key,value,next链表结构(当出现hash冲突的时候可以存放于此NODE后面)


HashMap源码阅读与理解HashMap源码阅读与理解HashMap源码阅读与理解

10、TreeNode 红黑树,当某个NODE链表超过阈值的时候,则转化成红黑树操作。


HashMap的几个方法:


HashMap源码阅读与理解

PUT方法,传入key和value调用putVal函数,深入剖析putVal方法:


HashMap源码阅读与理解

1、检查容器是否为空,resize()检查并修正容器大小,若超过加载因子*当前容量则扩大两倍生成新的容器将原来数值(如果有的话)赋值上去


HashMap源码阅读与理解

2、根据当前容器大小-1&hash值得到一个<=容器大小-1的值,判断在表中是否为空若为空则设置值进去。Tips:这也是为什么初始容量一定是2的幂次方


HashMap源码阅读与理解

3、如果不满足2中的情况,则当前已经有值,则判断hash值和key是否相等,如果相等则获得当前对象e。Tips:后面有一致操作,避免重复性代码。


HashMap源码阅读与理解

4、如果不满足3中的情况,但p是红黑树,则调用红黑树的方法加入节点


HashMap源码阅读与理解

5、不满足3、4的情况,则说明要去遍历这个链表看看是否有一样的(hash和key),有则e会被赋值与3操作类似,没有则加入链表尾部


HashMap源码阅读与理解

6、判断e是否为空,如果不为空则将value赋值进去


HashMap源码阅读与理解

7、modCount操作次数+1,判断是否超过限定容量,如果超过则resize(),回调函数afterNodeInserttion。