HashMap原理

HashMap的底层结构

  在JDK7中HashMap是通过“数组+链表”实现的,而JDK8中是通过“数组+链表+红黑树”实现的。数组作为哈希运算后的地址,链表和红黑树是为了解决哈希冲突,将哈希运算后相同的元素放到同一个哈希桶中。

HashMap的扩容机制

  HashMap数组的初始容量是16,扩容时以2的倍数扩容。是否要扩容由扩容因子决定,默认的扩容因子是0.75,当数组中的元素个数达到容量的0.75就会进行扩容。每个数组中的链表长度达到8时,就会将链表转换为红黑树,在转换前还会检查数组大小是否达到64,如果没有会先扩容数组在红黑树元素减少时,数量达到6才会退化为链表,这是为了避免频繁对哈希桶插入和删除的操作时链表长度在7和8之间变化,需要不断在链表和红黑树直接转换,消耗性能。
  扩容过程:假设hash算法是用key对数组大小取模。在数组扩容后,需要对表中的元素rehash,rehash后哈希桶中的元素会被分散到两个桶中,所以在数组大小小于64时进行扩容能使链表长度减小。
在这里插入图片描述
  JDK8中对扩容过程的优化:
  用位运算替代取模运算,用位运算提升了性能。
在这里插入图片描述  在重新计算hash值后,n变成2倍,n-1的mask的高位多了1。从上图可以看到,由于key1和key2的hash值的高位的值(这里为第5位)不同,两个值会被分配到两个哈希桶中。

HashMap的put

  JDK7用的是头插法,JDK8是尾插法,原因是用头插法在并发环境下,数组扩容可能会出现环。尾插法只能解决成环的问题,put的方法是没有加锁进行并发控制的,并发下的读写问题依然存在。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值