龙空技术网

java面试:为何重写equals就一定要重写hashCode?#程序员

云端行笔 239

前言:

今天各位老铁们对“java中方法重写的原则”可能比较着重,大家都想要剖析一些“java中方法重写的原则”的相关资讯。那么小编同时在网摘上汇集了一些关于“java中方法重写的原则””的相关文章,希望我们能喜欢,大家一起来了解一下吧!

为什么重写equals方法就必须重写hashCode方法呢?我们知道,Object类中的equals方法和hashCode方法非常特殊,它们之间存在着密切的联系。当我们重写equals方法时,就必须遵循一个原则,那就是必须重写hashCode方法,这是为什么呢?接下来,我们将详细探讨这个问题。

Object类的作者已经在源代码中进行了解释。在Object类中,我们可以看到有关注释的说明。从注释中,我们可以得出以下结论:如果两个对象equals方法的返回值为true,那么它们的hashCode值一定相等。如果两个对象的hashCode值不相等,那么它们也一定不相等。

Object类中的equals方法非常特殊,它的作用是判断两个对象是否相等。从官方注释中,我们可以得知它具有自反性、对称性和传递性。如果对equals方法的实现感兴趣,可以查看详细的注释内容。

另外,我们需要特别注意的是,在重写equals方法时,通常需要重写hashCode方法,以保证相等的对象具有相同的哈希值。因此,从根本上说,equals方法和hashCode方法是相互配套的。

为什么要这样设计呢?其实,Object类中的equals方法是通过等号(==)来比较两个对象的引用的。因此,只有当两个对象的内存地址值相同时,equals方法才会返回true。因此,如果我们想要比较两个对象的属性内容是否相等,就必须重写equals方法,而重写equals方法就必须重写hashCode方法。

例如,我们可以重写String类的equals方法,当两个对象的内容相等时,就返回true。

通过源码,我们可以看到,String对象在比较另一个对象时,除了地址值相同,还要求对应的每个字符也相同,才能被认为相等。即使地址值不同,也被视为相等。

接下来,我们来思考一个问题。如果我们不重写hashCode方法,而是继续使用Object类中的默认方法,会出现什么问题?此时,重写了equals方法的String类会根据地址值计算哈希值,而不是根据每个字符的Unicode码计算哈希值。这样就会出现一个问题:被String类中的equals方法认定为相等的两个对象,拥有不同的哈希值。

原来的问题是:“为什么重写equals方法就得重写hashCode方法”,现在我们知道了答案:因为必须保证重写后的equals方法,认定相同的两个对象拥有相同的哈希值。可能还有人会问:为什么要保证哈希值相等?不相等会有什么问题?继续分析。

在分析这个问题之前,我们先看一下某大厂的开发规范:只要覆写equals就必须覆写hashCode。因为Set存储的是不重复的对象,根据哈希值和equals进行判断,所以Set存储的对象必须覆写这两个方法。如果自定义对象作为Map的键,那么必须覆写hashCode和equals,带着这个规范,我们来看一下防腐Code的put方法。

从代码中可以看出,仅仅通过哈希值相等来证明两个对象是相同对象是行不通的,需要进一步的证明。即上图红框中,为了证明两个对象是同一对象,还要求二者哈希值相等。假设我们使用重写了equals方法,而未重写hashCode方法的String类型的值作为Key值。然后使用地址值不同,但字面量相同的两个同方向对象s1和s2,也就是字面相同(假设为"k"),但hashcod不同。

执行hashmap的put方法后,就会产生字面均为"k"的两个key,在hashmap中插入了两次值分别为v1和v2,这就会导致混乱。

通过以上分析,相信大家已经对重写equals和hashcode方法有了更深入的了解。欢迎留言讨论。

标签: #java中方法重写的原则