HashMap的底层实现原理

探讨HashMap在JDK7与JDK8中的实现差异,包括初始化、数据存储、链表与红黑树转换等关键概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

HashMap在JDK7中的底层实现原理
HashMap map=new HashMap();
在实例化以后,底层创建了长度是16的一维数组,类型为Entry类型,Entry[] table
用put方法put的数据,都是放在数组当中的,一个key-value对构成一个Entry

map.put(key1,value1);这里说的是普通的put的操作,可能已经执行过多次put
首先要知道放在数组中的哪个位置:
首先调用key1所在类的hashCode方法,计算key1的哈希值,此哈希值经过某种方法计算以后得到在Entry数组中的存放位置,如果此位置上的数据为空,意味着这个位置上没有数据,此时的key1-value1添加成功,添加到数组位置上的数据是Entry,是拿Entry中的key判断存放在哪里的标准而已,比的是一个一个的Entry,说的是key1-value1添加成功,实际上是Entry1添加成功

如果此位置上的数据不为空,也就是说这个位置上已经有数据了(意味着此位置存在一个或者多个数据(以链表的形式存在)),就要去比较当前数据的key1哈希值和已经存在的数据的key的哈希值,如果key1的哈希值和已经存在的数据的key的哈希值都不相同,此时不用调用equals方法,key1-value1添加成功,如果key1的哈希值和某一个数据(key2-value2)的key的哈希值相同了,则继续比较,调用key1所在类的equals方法key1.equals(key2),把哈希值相同的那个已有数据放到key1的equals方法的形参中,进行比较,如果方法返回的是false,则key1-value1添加成功,如果equals方法返回是true,就意味着两者的key是一样的,然后会使用value1替换相同key的value值(value2),此时相当于做了修改操作
如果添加成功,并且放的位置上已经有数据,所以是以链表的形式存放的,JDK8是新添加成功的元素放在最下面,JDK7是新添加成功的元素放到数组上面,这和HashSet是一样的。

在添加的过程中会涉及扩容问题,默认的扩容方式:扩容为原来容量的2倍,并将原有的数据都复制过来

JDK8相较于JDK7在底层实现的不同:
1.new HashMap():此时底层并没有去创建一个长度为16的数组
2.JDK8底层的数组是Node[],而非Entry[],其实本身里面的属性都没有变
3.首次调用put方法时,底层创建长度为16的数组(类似于ArrayListJDK7和JDK8的区别)
4.JDK7的底层结构只有数组加链表,JDK8中的底层结构:数组+链表+红黑树
当数组的某一个索引位置上的元素以链表形式存在的数据个数>8,且当前数组的长度>64,此时此索引位置上的所有数据改为用红黑树存储。优点:遍历快,方便查找,因为假设这个位置上有好几个元素,在JDK中要找元素,上来就用hashCode定位到这个位置,但因为这个位置上有好几个元素,就要一个一个比,相当于把这些元素遍历一遍,效率低

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值