HashSet&HashMap存放数据有趣现象

文章讲述了在处理HashMap时,通过修改对象属性导致的HashCode变化影响了Set的存储行为,特别是equals方法被重写后,对象的存储位置并非仅基于原HashCode。作者揭示了HashSet底层的存储逻辑,包括单项链表的形成。
摘要由CSDN通过智能技术生成

今天学习集合最后一章节的时候,一道练习题让我对HashMap的底层结构的有了一个新的认知。

注:题目中的HashCode和equals方法会根据id和name来产生。

笔者第一次做错了,原因是认为在执行set.remove的时候,去除的就是HashMap指向的对象。

现在来讲解一下这个题目。

当添加了两个对象后,set的数据结构应该是这样(这里的hashcode是假设的):

当我们修改p1中name的值,那么就会在table节点为1的地方修改p1。请注意!这个时候没有使p1的存放位置发生改变,而仅仅是改变了数值。

随后我们执行了移出p1的操作。但!这个时候我们使用p1定位到的地址是new Person(1001,“CC”)这个对象所产生的HashCode(从题干中可知,这个对象的Hash产生方法已经被我们重写,所以HashCode会根据p1的数值发生变化)。

所以移除的操作是失败的!!!

此时输出的set有两个对象,一个是p1,一个是p2

随后,我们加入了一个新对象,这个新对象产生的hashCode和我们remove操作所定位的位置一样

,不会和之前的冲突,即使属性相同。这个时候的存储内容应该是这样:

所以此时输出的对象有三个p1,p2,new Person(1001,“CC”)

最后我们添加了一个和P1对象初始属性值一样的对象,所以产生的hashCode会和P1一开始一样。

HashSet底层存储需要看两个地方,一为HashCode,二为equals。通过题干可知,equals方法已经被Person类重写,根据属性来对比。所以新加入的这个对象虽然会定位地址和p1一样,但是会挂到p1节点后面,形成单项链表

此时的结构应该是这样:

所以最终的结果会输出四个对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值