Java之HashSet除重原理

HashSet的除重原理判断HashCode方法,判断equals方法,若两者同时返回true则认为对象与集合中对象重复,若HashCode返回false则不再执行equals。

HashCode方法:根据一套特殊的计算方法返回一个整形值,此值被HashSet用来定位对象的存储地址

equals方法:判断两个对象的内容是否相等。

除重判断流程:HashSet会将新增对象与集合中的每一个对象进行对比,若都不重复则添加,重复则不添加。

--------------------------------------------------------------------------分割线--------------------------------------------------------------------------

除重时判断会出现以下两种特殊情况:

①若HashCode判断返回true,但是equals方法返回false。

        若HashCode方法返回true,equals方法返回false,此时HashSet认为两个对象不相同。但是因为HashCode返回值为true,而HashSet又是根据对象的HashCode值定位其存储地址,这时两个对象的HashCode值相同就出现了存储冲突,虽然对象不一样但是计算机计算其在内存中的存储位置是一样的,为了解决冲突此时将多个不同对象以链式的方式保存在一个位置。因为HashSet访问是根据HashCode值定位对象,此时有多个对象在一个地址用链表保存,会导致HashSet访问性能下降。

②若HashCode判断返回false,但是equals方法返回true。//此时的equals返回true是我们人为知道的,系统并未执行equals

        若HashCode判断返回false,equals方法返回true时,虽然两个对象内容是相同的但是系统依然会将对象存储进集合。因为HashSet方法除重时是先访问HashCode方法,所以若HashCode方法返回false此时系统会认为对象不同,然后直接根据计算出的HashCode返回值定位到相应存储地址将对象存进去,不会再继续访问equals方法判断内容是否相同,所以此时无法达到除重效果。

        代码演示:在worker类中重写hashCode方法和equals方法。为了方便看出当HashCode方法返回false时是否会继续执行equals方法判断对象是否相等,我们加一条代码若执行则会显示一次“我执行了”。

主代码;

输出结果:

分析:在重写的HashCode中我将年龄作为返回值,在quals中认为名字和工号相同则为重复,不判断年龄。但是输出结果显示添加了重复对象,并且没有输出一条“我执行了”。所以当HashSet判断所添加对象与集合中的对象HashCode不相等时则不会再继续执行equals方法,会直接保存对象。

        //有的人会好奇为什么不同的对象却HashCode返回值会一样,这是因为系统计算方法的问题,导致了即使对象不同也有小概率会出现HashCode值相同的情况。

总结:若调用系统自带类则无需重写HashCode和equals方法,系统已经写好。若要将自定义类存入HashSet去除重,则需重写HashCode和equals方法实现除重效果。重写要求HashCode方法对于相同的对象返回值必须相同,不同的对象返回值尽量不同以提高效率。

觉得有用的小伙伴请点赞、评论或收藏一下多支持支持博主小弟,跪安~~

  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值