关于作者:毕业半年被裁,一个月斩获大厂offer,面试经验50+。“跟着周哥走,offer手里有”。文末免费领取周哥50+场面试总结出的必背面试题。
首先我们要知道,equals()和hashCode()都属于Object类,而Object类是所有类(包括Class)的父类。
搞清楚这一点,再分别解析equals和hashCode,然后作出对比。最后,给出关于equals和hashcode重要面试题及答案。
equals()
解析
- 作用:用于引用数据类型,判断一个对象是否等于另一个对象,可以重写 equals 方法自定义比较规则。
==和equals的区别
- 如果变量是基本数据类型,那么使用==比较变量的值。
- 如果变量是引用数据类型,==仍然比较变量的值(不忘初心),只不过这个值是对象的地址。
- equals只能作用于引用数据类型。 equals如果没有重写,比较的是引用变量的值,即对象地址。equals重写之后,比较的是对象的内容。例如使用equals比较String的value值是否相等。
hashCode()
解析
- 作用:hashCode() 的作用是获取哈希码,也称为散列码,其作用是将对象的地址值(即引用变量)映射为integer类型的哈希值。这个哈希码的作用是确定该对象在哈希表中的索引位置。
注意,字符串(String类型)可能有相同的散列码。这是由于String类型中重写了hashcode方法。
看下图可知,String类型的字符串值是保存在value中的。而value会保存在字符串常量池中。
比如,
s1 = "123";
\s2 = "123";
s1和s2的引用变量,即对象的地址,是不同的。但由于s1和s2的引用对象的value数组值是相同的。故,在计算哈希值时,s1和s2的就会得到相同的哈希值。
hashCode()和equals()面试题解析
1. hashCode() 和 equals() 两种方法之间有什么关系?
答:
为了在集合类HashMap或HashSet中正确使用散列码,需同时重写 equals 和 hashCode 方法。
两对象比较时,先比较hashCode后比较equals。equals 相同时 hashCode 必相同,但 hashCode 相同时 equals 未必相同。hashCode 是两个对象相同的必要不充分条件。
即:
equals相同<=>对象相同
对象相同=>hashcode相同
否命题:hashCode不同=>对象不同
2. 为什么hashcode相同时,equals不一定相同?
答:有时候不同的对象,hashcode的值可能也会相同,例如:
所以说,hashCode()并不可靠。
equals由于比较的是对象的值,值相同与否是可以确定的,所以是可靠的。
3. 为什么不直接equals比较值是否相同,而先要计算hashCode?
答:
hash算法是二进制算法,计算式本质是二进制,所以hash算法速度很快。如若hashCode不同则可直接存储不用equlas比较。所以先计算hashCode大大加快了存储速率。
4. 为什么重写equals后必须重写hashcode?
答:
Object类的equals()方法上方的注释里有写到:当我们将equals方法重写后有必要将hashCode方法也重写,这样做才能保证不违背hashCode方法中“相同对象必须有相同哈希值”的约定。
由此可见,重写equals后必须重写hashcode是为了保证重写后的equals方法认定相同的两个对象拥有相同的哈希值。
至于equals相同hashcode也必须相同的原因,是为了与Java集合配套使用。
我们可以以hashSet实现去重功能为例,hashSet底层是通过HashMap来实现的,查看源码可以发现HashMap中的Hash()方法,是调用了key.HashCode()。
我们假设自定义一个学生类型Student,且Student只重写了equals方法。然后,new出两个属性值完全一样的对象,将其先后添加到HashSet中。
查看HashMap中的putVal()方法可知,
会将传入学生对象的hash值与(数组长度-1)进行&操作,得到数组的下标值。但是由于学生类型,没有重写hashCode,则其hashcode()方法默认是通过对象的地址值的得出。
由于两个学生对象的地址值不同,因此哈希值不同。那么,根据哈希值计算出的索引位置就会不同,则会将两个学生对象存入不同的数组位置。但是,由于equals是根据学生信息计算的,所以equals是相同的。这就违背了hashset的去重功能(hashset不会将相同的对象存到数组中)。因此,必须重写HashCode()方法。
5.会自定义子类重写equals吗?
答:示例如下
好了,到此为止,关于hashcode和equals的知识点大家应该有个深刻的理解了。
以上内容出自本人整理的面试秘籍。
链接: https://pan.baidu.com/s/1o014Ems8diV0D3h8K15olA?pwd=fi3x 提取码: fi3x 复制这段内容后打开百度网盘手机App,操作更方便哦
工作日每天更新,周末随缘更新。
请关注我,以便及时获取最新内容哦!
本文由mdnice多平台发布
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。