其他分享
首页 > 其他分享> > 面试部分难点梳理 - HashMap + CurrentHashMap

面试部分难点梳理 - HashMap + CurrentHashMap

作者:互联网

HashMap

视频
在这里插入图片描述

HashMap的继承体系

在这里插入图片描述

核心属性+构造方法

状态属性:

成员属性

putVal()方法

Hash扰动处理

延迟初始化,

第一种情况:Hash数组中没有元素

第二种情况:Hash数组中有元素并正是我们要找的

第三种情况:Hash数组中有元素,不是我们要找的找到,并且其数据结构是红黑树

第四种情况:Hash数组中有元素,不是我们要找的找到,并且其数据结构是链表

上面的四种情况都会落到这里。

resize()方法

确定参数

第一种情况:散列表已经初始化过了,正常扩容

第二种情况:散列表没有被初始化过,但是有负载因子(对应HashMap的有参构造)

在这里插入图片描述

第三种情况:散列表没有被初始化过,且没有负载因子(对应HashMap的无参构造)

在这里插入图片描述

第四种情况:散列表第一次被有参初始化时,或newCap大于MAXIMUM_CAPACITY或oldCap < DEFAULT_INITIAL_CAPACITY,时设定newThr。

扩容操作

让e作为节点遍历oldTab[j],同时oldTab[j] == null,辅助GC。

在这里插入图片描述

第一种情况:数组仅仅有一个数据

第二种情况:数组有且数据结构为红黑树

第三种情况:数组有且数据结构为链表

get()和remove()

getNode()

第一种情况:数组中相应索引的第一个元素就是

第二种情况:数组中响应索引的第一个元素不是,数据结构是红黑树,然后遍历红黑树

第三种情况:数组中响应索引的第一个元素不是,数据结构是链表,然后遍历链表

上面三种都没找到,那就没有返回null

removeNode()

查找

删除

ConcurrentHashMap JDK1.7

构造函数

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
初始时只有第一个segment会初始化两个hashentry,后面的是不会被初始化的,只有在用到才会被初始化

Segment继承了ReentrantLock

put()

rehash()

获取集合长度size()

ConcurrentHashMap JDK1.8

  • sizeCtl为0,表示数组未初始化,且数组初始化容量为默认值16
  • sizeCtl为正数,如果数组未初始化,那么sizeCtl表示的是数组的初始化容量。如果已经初始化,则表示数组的扩容阈值。
  • sizeCtl为-1,表示数组正在进行初始化。
  • sizeCtl为小于0,表示数组正在扩容,其值为-(n-1)时,表示有n个数组正在扩容,共同完成对数组的扩容。

初始化

默认初始化(不推荐)

带有初始容量的初始化

全参初始化

添加安全

数组初始化(多次自旋进行CAS)

数值添加(四种情况)

第一种情况:数组当前索引处没有元素

第二种情况:数组当前索引处有元素,并且正在进行扩容,则启动多线程辅助扩容。

对于下面两种情况是上锁的

第三种情况:数组当前索引处有元素,元素数据结构是链表

第四种情况:数组当前索引处有元素,元素数据结构是红黑树

树化判断

在这里插入图片描述

维护集合长度

在这里插入图片描述

集合长度获取

扩容安全

协助扩容的两种情况

标签:扩容,初始化,HashMap,难点,链表,CurrentHashMap,数组,长度,节点
来源: https://blog.csdn.net/paleatta/article/details/123626434