jdk 1.8 hashmap和1.7 hashmap区别 原理解析

本文详细分析了JDK 1.7和1.8 HashMap在并发扩容时可能导致死循环的问题,以及1.8版如何通过尾插法和红黑树优化避免该问题。1.8版引入了数组+链表+红黑树的数据结构,减少了Hash冲突,提高了存储和检索效率。在扩容策略上,1.8版选择在插入数据成功后进行扩容,与1.7版不同。
摘要由CSDN通过智能技术生成

@[TOC](`jdk 1.8 hashmap和1.7 hashmap区别 原理解析)
#在jdk中,目前使用比较多的主要是1.8,主要是因为1.8在1.7的基础上优化了很多内容,尤其是hashmap这个集合 在内部结构和实现上都是进行了优化和调整。下面主要讲了1.7发生死循环的原因和过程,以及1.8在添加元素的实现,最后总结了1.7和1.8的主要区别。

part1:hashmap比较

	   通过jdk的源码我们可以了解到,1.8在1.7的基础上,hashmap做了比较大的改动,下面具体说明:

1.7 hashmap

		简单来说:*Entry数组+链表*的结构;插入数据使用*头插法*

我们都知道hashmap是线程不安全的,但是如果被用在了多线程上,1.7的hashma是有可能导致死循环,这是程序绝对不允许的。产生死循环的情况主要是在多线程下,进行put操作的时候,hashmap的Entry 链表有可能形成环形数据结构,一旦形成环形数据结构 Entry 的 next 节点永远不为空,就会产生死循环获取 Entry。
通过源码我们可以了解到,引发死循环,是在 HashMap 的扩容操作中。正常的扩容操作是这个流程。HashMap 的扩容在 put 操作中会触发扩容,主要是三个方法
在这里插入图片描述
综合来说,HashMap 一次扩容的过程:
1、取当前 table 的 2 倍作为新 table 的大小
2、根据算出的新 table 的大小 new 出一个新的 Entry 数组来,名为 newTable
3、轮询原 table 的每一个位置,将每个位置上连接的 Entry,算出在新 table上的位置,并以链表形式连接
4、原 table 上的所有 Entry 全部轮询完毕之后,意味着原 table 上面的所有Entry 已经移到了新的 table 上,HashMap 中的 table 指向 newTable

这里用一个实例说明死循环的产生

【正常情况的扩容】:
现在 hashmap 中有三个元素,Hash 表的 size=2, 所以 key = 3, 7, 5,在 mod 2
以后都冲突在 table[1]这里了
在这里插入图片描述
按照源码中扩容的最后一步,把原数组移动到新数组的过程
在这里插入图片描述
对 table[1]中的链表来说,进入 while 循环,此时 e=key(3),那么 next=key(7),经过计算重新定位 e=key(3)在新表中的位置&#x

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值