hash:hash值
value:存储元素
key:键
onlyIfAbsent: 如果是true,则不改变已存在的value值
tab:数组+链表 数组index定位链表所在位置
p:链表 存储的数据
从源码可以看出第一次tab为空,tab需要默认resize()扩容一次,第一次扩容的长度为16
Node<K, V>[] tab
扩容原理这里暂不做解释
hashMap第一次put数据
tab[hash & (length-1)]定位数组是否存在node节点
定位原理
length第一次为16
table扩容后长度length为32
如果与已存在的Node是相同的key值,取出重复的数据 Node<K,V> e
如果与已存在的Node是相同的key值,并且是树节点,树节点数据覆盖,取出重复的数据 Node<K,V> e
如果与已存在的Node是相同的key值,并且是普通节点,则循环遍历链式Node,并对比hash和key,如果都不相同,则将新的Node拼装到链表的末尾,同时将新的Node<K,V>的next置位null,如果相同,则进行更新
如果Node链表大于8个Node,尝试转为红黑树
如果table的length没有达到64的长度,会继续扩容不会转为红黑树
Node<K,V> e表示是否存在重复Node,直接执行更新操作
第一次resize()
table长度length为16
threshold=16*0.75=12 阈值
当size大于阈值threshold(默认值12)时,table会再次扩容
总结:
第一次put数据的时候resize()扩容一次 table长度 16 threshold(阈值)12
当size<threshold(阈值)的时候resize()扩容一次 table.length*2 threshold(阈值)*12
当table中的Node链表大于8个Node且table的长度小于64的时候 resize()扩容 table.length*2 threshold(阈值)*12
当table中的Node链表大于8个Node且table的长度大于64的时候 将链表转为红黑树