为什么重写equals必须重写hashCode的基础分析
为什么重写equals必须重写hashCode的基础分析
1.我们先来了解下原生的equals和hashCode代码
原生equals:它判断的是两个对象是否相等
原生hashCode值:它是根据内存地址换算出来的一个整数类型的值
2.至于为什么要重写equals和hashCode?
当然为了满足我们具体的业务需求啦,毕竟我们不一定只比较对象相等嘛
3.做一个超简单小案例来理解下(包名不规范,切勿模仿);
(1)创建一个Student类,不重写equals和hashCode
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | package 重写equal必须重写hashcode; public class Student { public String id; //学生的id public String name; //学生的名字 public Student() { super (); // TODO Auto-generated constructor stub } public String toString() { return id + ":" + name; } public Student(String id, String name) { super (); this .id = id; this .name = name; } } |
(2)new一个hashSet,分别添加三个student
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | package 重写equal必须重写hashcode; import java.util.HashSet; public class Test { //学生ID和姓名都相同我们视为重复 public static void main(String[] args) { HashSet hs = new HashSet(); hs.add( new Student( "001" , "小明" )); hs.add( new Student( "002" , "小花" )); hs.add( new Student( "002" , "小花" )); System.out.println(hs); } } |
(3)运行结果如下:
(4)我们可以看到,信息出现了重复;new的对象不同生成的hashCode值不同,所以hashSet会把三个Student对象当作不同的对象。
2.接下来我们重写equals而不重写hashCode
(1)重写equals后代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | package 重写equal必须重写hashcode; public class Student { public String id; //学生的id public String name; //学生的名字 public Student() { super (); // TODO Auto-generated constructor stub } public String toString() { return id + ":" + name; } public Student(String id, String name) { super (); this .id = id; this .name = name; } public boolean equals(Object obj) { if ( this == obj) { //判断是否是同一对象 return true ; //同一类型返回true(跟自己比较) } if (getClass()!=obj.getClass()) { //判断是否为同一类型 return false ; //不是同类型返回false(类型不同肯定为不同的对象) } Student stu = (Student)obj; //强制转换成Student类型 boolean result = this .id.equals(stu.id); //判断ID是否相等 return result; //返回判断结果 } } |
(2)现在我们运行下,结果如下图:
(3)可以发现重复的信息没有删除掉,可以判断添加Student对象没有调用equals方法,而是根据hashCode值的不同,hashSet就认为三个对象不相等。
3.最后我们重写equals和hashCode;
(1)重写hashCode;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | package 重写equal必须重写hashcode; public class Student { public String id; //学生的id public String name; //学生的名字 public Student() { super (); // TODO Auto-generated constructor stub } public String toString() { return id + ":" + name; } public Student(String id, String name) { super (); this .id = id; this .name = name; } public boolean equals(Object obj) { if ( this == obj) { //判断是否是同一对象 return true ; //同一类型返回true(跟自己比较) } if (getClass()!=obj.getClass()) { //判断是否为同一类型 return false ; //不是同类型返回false(类型不同肯定为不同的对象) } Student stu = (Student)obj; //强制转换成Student类型 boolean result = this .id.equals(stu.id); //判断ID是否相等 return result; //返回判断结果 } public int hashCode() { //重写hashCode return id.hashCode(); //返回ID属性的哈希值 } } |
(2)运行结果如下:
(3)是不是就把重复的信息移除了呢?哈哈
如果有不妥之处,请各位大佬多多包涵,这些也是个人的理解
如果你有补充,欢迎留下你的意见在评论区!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~