这篇文章主要介绍“为什么要重写equals和hashcode”,在日常操作中,相信很多人在为什么要重写equals和hashcode问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”为什么要重写equals和hashcode”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
首先我们分别解释equals()方法和hashCode()方法分别是用来做什么的?
我们再来看equals()方法和hashCode()方法两者有什么关系?
最后来看为什么重写equals()就一定要重写hashCode()方法?
equals()方法:
很明显,该方法就是用来判断两个对象是否是同一个对象。在Object类源码(如下所示)中,其底层是使用了“==”来实现,也就是说通过比较两个对象的内存地址是否相同判断是否是同一个对象。
public boolean equals(Object obj){ return (this == obj); }
但是在实际应用中,该方法不能满足的我们的需求。因为我们认为两个对象即使不是指向的同一块内存,只要这两个对象的各个字段属性值都相同,那么就认为这两个对象是同一个对象。所以就需要重写equals()方法,即如果两个对象指向内存地址相同或者两个对象各个字段值相同,那么就是同一个对象。
hashCode()方法:
一提到hashcode,很自然就想到哈希表。将某一key值映射到表中的一个位置,从而达到以O(1)的时间复杂度来查询该key值。Object类源码(如下所示)中,hashCode()是一个native方法,哈希值的计算利用的是内存地址。
public native int hashCode();
可以认为利用哈希表也能起到一定的判重的作用,但是现实是可能存在哈希冲突,即使是两个不同的对象,他们的哈希值也可能相同,如何解决哈希冲突,这里就略略略了。总之,我们记住哈希表具有优越的查询性能,并且存在哈希冲突。
两者事实关系如下:
如果两个对象相同(即用equals比较返回true),那么它们的hashCode值一定要相同!!!!;
如果两个对象不同(即用equals比较返回true),那么它们的hashCode值可能相同也可能不同;
如果两个对象的hashCode相同(存在哈希冲突),那么它们可能相同也可能不同(即equals比较可能是false也可能是true)
如果两个对象的hashCode不同,那么他们肯定不同(即用equals比较返回false)
对于对象集合的判重,如果一个集合含有10000个对象实例,仅仅使用equals()方法的话,那么对于一个对象判重就需要比较10000次,随着集合规模的增大,时间开销是很大的。但是同时使用哈希表的话,就能快速定位到对象的大概存储位置,并且在定位到大概存储位置后,后续比较过程中,如果两个对象的hashCode不相同,也不再需要调用equals()方法,从而大大减少了equals()比较次数。 所以从程序实现原理上来讲的话,既需要equals()方法,也需要hashCode()方法。那么既然重写了equals(),那么也要重写hashCode()方法,以保证两者之间的配合关系。
• 开放定址法: 这种方法也称再散列法,其基本思想是:当关键字key的哈希地址p=H(key)出现冲突时,以p为基础,产生另一个哈希地址p1,如果p1仍然冲突,再以p为基础,产生另一个哈希地址p2,…,直到找出一个不冲突的哈希地址pi ,将相应元素存入其中。这种方法有一个通用的再散列函数形式: • 线性探测再散列: 这种方法的特点是:冲突发生时,顺序查看表中下一单元,直到找出一个空单元或查遍全表。 • 二次探测再散列 这种方法的特点是:冲突发生时,在表的左右进行跳跃式探测,比较灵活。
到此,关于“为什么要重写equals和hashcode”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。