面试题:我们重写一个对象的时候为什么要同时重写hashcode()和equals()方法

在创建的类不重写hashCode()和equals() 方法时,默认使用 java 提供的 java.lang.Object 下的 hashCode()和equals() 方法。

注意:Object 的public boolean equals(Object obj)方法主要是对非空对象的引用地址的判断相同才返回true,而非对象本身的字符串内容或数值是否相同。

简而言之,当且仅当 值A 和 值B 都是引用自同一个对象时,此方法才会返回true;

所以,当我们重写一个对象,重写了equals()方法后,通常必须重写 hashCode()方法,以维护 hashCode 方法的常规协定,该协定声明了相等对象必须具有相等的哈希码。

说白了,就是equals 返回true的两个值,在hashCode() 中结果也必然是true。

例子:
(1)当obj1.equals(obj2)为true时,obj1.hashCode() == obj2.hashCode()必须为true
(2)当obj1.hashCode() == obj2.hashCode()为false时,obj1.equals(obj2)必须为false

这里引出一个问题,为什么要重写equals()方法呢?难道原生的不能用吗?

答案是必须重写,从前面的注意事项中可以知道,如果不重写equals 方法,那么比较的将是对象的引用是否指向同一块内存地址,而我们重写的目的是为了能够比较两个对象的value值是否相等。

在高级类的八个包装类与引用类型的String类型(该类对euqals和hashcode方法进行了重写)中都 是使用重写后的 equals 方法来比较对象的,默认比较的是值,在比较其它自定义对象时都是比较的引用地址。

后面会对equals 和 hashcode 的关系进行关联解释。

hashcode是用于散列数据的快速存取,如利用HashSet/HashMap/Hashtable类来存储数据时,都是根据存储对象的hashcode值来进行判断是否相同的。

扫描二维码关注公众号,回复: 9077896 查看本文章

那么,如果我们值重写equals ,而不重写 hashcode 会怎么样?

如果我们对一个对象重写了equals 方法,意味着只要对象的成员变量值都相等那么equals 就返回true ,但在不重写 hashcode 方法的情况下,当我们重新 new 了一个新对象。
此时,当原对象.equals(新对象)等于true时,两者的 hashcode 却是不一样的,由此会产生了理解的不一致,也违反了equals 与 hashcode的约定规则。

不重写导致的结果案例:

在不重写hashcode的情况下,如果 hashset存储两个引用不同但值相同的对象,此时hashcode返回false,认为后者与前者不重复,则会重新 newNode() 创建一个新节点将重复的值添加到集合中,意味着不可重复的单列集合中出现了两个值一样的对象,导致混淆。(假设没有重写)

所以,需要重写 hashcode()方法。

发布了222 篇原创文章 · 获赞 60 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/weixin_42405670/article/details/104030405
今日推荐