您的位置:首页 > 新闻 > 资讯 > Java-为什么重写equals的时候“必须“要重写hashCode

Java-为什么重写equals的时候“必须“要重写hashCode

2025/3/15 5:09:51 来源:https://blog.csdn.net/u011624903/article/details/141031072  浏览:    关键词:Java-为什么重写equals的时候“必须“要重写hashCode

这是一个有意思的问题,看标题就知道,我将必须两个字用引号引用了起来,首先,我要说一下我的观点
1.写这篇文章的原因就是因为网上很多人不懂还乱说,给人造成误解,我对这种一知半解,甚至无知的程序员极度愤恨
2.重写hashCode的必须性,没有那么的强烈,它只是作为八股文面试忽悠小白而已

先说结论,Java中为什么重写equals的时候必须要重写hashCode
如果你看到除了本文我所说的原因,还有其他原因,那么你应该好好思考一下,我说的对,还是其他人说的对,重写hashCode最根本的原因就是基于Object类中的equals()hashCode()两个方法上的的注释,注释上写的非常清楚了,如下

Note that it is generally necessary to override the hashCode method whenever this method is 
overridden, so as to maintain the general contract for the hashCode method, which states that 
equal objects must have equal hash codes.

这句话翻译过来就是,equals和hashCode方法之间有一个我们人为的一般约定,如果不遵循这个约定,我们的代码会导致可读性、可维护性和可预测性下降。

言外之意也可以说这个注释强调了约定优于配置的重要性,看下面的代码

public class User{public String name;// 我们简单的重写equals,不考虑null和obj不是User实例的情况public boolean equals(Object obj) {// 只要两个对象name相同,那么就认为是同一个对象return name.equals(((User)obj).name);}
} 

接下来我们创建一个main方法

public static void main(String[] args) {User u1 = new User();u1.name = "抱抱";User u2 = new User();u2.name = "抱抱";Map<User, String> map = new HashMap<>();map.put(u1, "值1");System.out.println(map.get(u2));// 这个地方是null
}

现在我们要讨论本文的重点,就是get(u2),你希望他的结果是什么?
结果1:如果你的需求希望输出"值1",我认为这是没错的,因为u1和u2在逻辑上是相等的,它应该返回"值1"
结果2:如果你的需求希望输出null,我认为这也是没错的,因为从技术角度来说,hashmap是通过数组下标存储数据的,u1和u2的hashCode不等,它理应返回null

现在两个结果都有各自的理由站住,所以需要有一个约定,来让大家选举出一个相对正确的结果(不考虑业务需求的情况下),结果我们都觉得实战中,结果2的业务需求是不常见的,少见的,所以才有了这个约定

假设没有这个约定,并且我就是需要结果2,那么本次代码维护人员离岗,下一个维护人员来的时候,将对这段代码非常的困惑,他不知道1和2哪个正确,在不清楚业务的情况下,非常的难以预测,这,就是为什么重写equals的时候"必须"要重写hashCode的根本原因

所以为什么重写equals的时候必须要重写hashCode这个问题它本质上是个对编码规范和编码习惯的问题,而不是我们平常的技术问题,它不倾向于技术,我重写equals不写hashCode,不会对代码的任何性能和结果产生影响,主要就是难以维护

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com