让星星⭐月亮告诉你,HashMap底层数据结构及其增put删remove查get方法的代码实现原理

31 篇文章 0 订阅
10 篇文章 0 订阅

PS:由于文档是我在本地编写好之后再复制过来的,有些文本格式没能完整的体现,故提供下述图片,供大家阅览,以便有更好的阅读体验:
在这里插入图片描述

1.HashMap底层数据结构是数组+链表(jdk1.7头插法<扩容时链表逆序可能会导致环形链表的问题出现> jdk1.8尾插法)+红黑树(jdk1.8).
2.HashMap中数组的容量默认为16,负载因子默认为0.75,当数组的0-15个下标里有16×0.75=12个被使用时,且HashMap中存储的元素总个数大于64时,则发生扩容操作,数组的容量扩大为原来的2n.
3.负载因子代表数组中存储数据密度的大小:负载因子越大,数组单位容量内存储的数据越多,不同元素之间(key不同,但计算得到的数组下标相同)越容易发生碰撞(哈希碰撞);反之,则单位容量内存储的数据越少,越不易发生碰撞.
4.put(key,value)时的处理逻辑:
(1)hash(key) = (key==NULL)?0:(h=key.hashCode())^(h>>>16),即取key的原始哈希码的高低16位进行异或位运算,计算出一个经高低位混合后高低位分布更加均匀的新哈希码,再用该新哈希码和数组容量减一做与位运算(hash(key)&(2^n-1))得出要存放的数组下标[当HashMap的容量是2的n次幂时,(2^n-1)的二进制就是11111*111全1的形式,这样与hash(key)进行与的位运算时,能够充分的散列,使得添加的元素均匀分布到HashMap的每个位置上,减少hash碰撞],可以一定程度降低根据不同元素计算得出相同数组下标(哈希碰撞)的概率;
(2)得出的数组下标里已经存放有数据元素,则根据key的值遍历比较该下标下的链表或红黑树,如果遇到相同key,则更新key对应的value值后返回(return);若遍历链表后未遇到相同的key,则在链表(jdk1.7头部 jdk1.8尾部)或红黑树合适位置(可能触发红黑树的左旋右旋或颜色改变),插入新的(key,value)键值对元素(插入值时统计存储的总元素个数的变量值会加一) ;
(3)某链表插入新的键值对后,可能导致该链表的长度大于等于8,若此时数组存储的总元素个数大于等于64,则将链表转为红黑树(保证最好最坏情况下时间复杂度为以2为底总元素个数n的对数级别,以提高增删查处理性能);
(4)链表插入新值后,也可能会触发数组扩容操作
5.get(key)时的处理逻辑:同put(key,value)的步骤(1),会根据key值计算得出数组下标,然后用key值遍历比较该数组下标下的链表或或红黑树,找到相同key对应的value值并返回,否则,返回null;
6.remove(key)时的处理逻辑:同get(key)和put(key,value)的步骤(1),会先根据key找到要删除元素所在位置,然后进行删除操作;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Dylanioucn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值