3、HashMap详解

一、底层结构

数组+链表+红黑树

二、扩容

1、条件

元素个数超过数组长度✖️负载因子(默认0.75) 

数组长度小于64,链表长度大于8

2、过程

1.7前头插法在多线程下容易死循环(环形链表)

1.8后改为尾插法

3、元素迁移

java1.8之后

1、元素e,hash值,数组下标(索引)

c763aad76a514b1eb52886c800f7b7dd.png

4d747bc53c3e44b9806fb0f8d4f9dbc8.png

2、hash值&(n-1)

扩容前后的数组下标计算

6f7f2aa5e5834d5c935f09ec0aa8af49.png

0101为5,10101为21

又21=5+16;

3、扩容后的索引值

在扩容时

不需要重新计算元素的hash进行元素迁移,

用原先位置key的hash值&旧数组的长度。

如果结果为0,桶位置不变。

如果结果不为0,桶位置就是当前元素原来的

数组下标+旧数组长度。

4、总结

扩容前后的索引下标相差一个Bit位,可知:

若hash值&扩容前数组长度为0,则扩容后的数组下标不变。

若不为0,则扩容后的数组下标为扩容前的数组下标+扩容前的数组长度。

三、链表转红黑树

1、条件

数组长度大于64,链表长度大于8

2、红黑树特征

根节点都为黑色

每个节点,到其叶子节点的所有路径,包含相同数目的黑色节点

3、优点

相比于二叉查找树,可以避免单一链表,

增加查找效率。

四、多线程下存在的问题

1、put数据覆盖。

2、put导致扩容,再get导致为null。

3、扩容1.7时头插法会出现环形链表,死循环;1.8采用尾插法。

五、线程安全使用concurrenthashmap

  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值