集合相关梳理

HashMap的底层结构

从jdk1.8之后,hashmap底层采用【数组+链表+红黑树】的结构,1.8之前是【数组+链表】

hashmap底层结构:

hashmap底层为啥要使用数组+链表?

使用 “数组+链表” 是为了解决 hash 冲突的问题
数组和链表有如下特点:
数组:查找容易,通过 index 快速定位;插入和删除困难,需要移动插入和删除位置之后的节点;
链表:查找困难,需要从头结点或尾节点开始遍历,直到寻找到目标节点;插入和删除容易,只需修改目标节点前后节点的next 或 prev 属性即可;
HashMap巧妙的将数组和链表结合在一起,发挥两者各自的优势,使用一种叫做 “ 拉链法 的方式来解决哈希冲突。
首先通过index 快速定位到索引位置,这边利用了数组的优点;然后遍历链表找到节点,进行节点的新增 / 修改 / 删除操作,这边利用了链表的优点。

1.8之后咋又引入红黑树呢?

引入红黑树是优化查找性能

通过上面可以看出, 数组 + 链表 已经充分发挥了这两种数据结构的优点,是个很不错的组合了。
但是这种组合仍然存在问题,就是在定位到索引位置后,需要先遍历链表找到节点,这个地方如果链表很长的话,
也就是 hash 冲突很严重的时候,会有查找性能问题,因此在 JDK1.8 中,通过引入红黑树,来优化这个问题。
使用链表的查找性能是 O(n),而使用红黑树是 O(logn)

链表和红黑树的使用时机

对于插入,默认情况下是使用链表节点。当同一个索引位置的节点在新增后超过 8 个(阈值 8 ):如果此时数组长度大于等于 64 ,则会触发链表节点转红黑树节点( treeifyBin );
而如果数组长度小于 64 ,则不会触发链表转红黑树,而是会进行扩容,因为此时的数据量还比较小。
对于移除,当同一个索引位置的节点在移除后达到 6 个(阈值 6 ),并且该索引位置的节点为红黑树节点,会触发红黑树节点转链表节点(untreeify )。

hashmap的重要属性

为什么初始容量是16,扩容必须是2的n次幂呢?

为了加快哈希计算以及减少哈希冲突

当数组长度为2的n次幂的时候,不同的key算得得index相同的几率较小,那么数据在数组上分布就比较均匀,也就是说碰撞的几率小,相对的,查询的时候就不用遍历某个位置上的链表,这样查询效率也就较高了。

hashmap的插入流程

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值