学习:重写hashCode()方法的必要性
当一个类有可能会和其他类发生比较的时候,我们会重写equals方法,但大多数情况下,都忽略了重写hashCode方法。
这里说一下重写hashCode的必要性。
当我们使用HashSet或者HashMap的时候,在比对value|key是否存在时,会调用hashCode方法。
注意,hashSet的contains方法其实是依赖于HashMap的containsKey方法的。
我们来看下containsKey方法的实现:
public boolean containsKey(java.lang.Object paramObject) { return (getEntry(paramObject) != null); } final Entry<K, V> getEntry(java.lang.Object paramObject) { int i = (paramObject == null) ? 0 : hash(paramObject.hashCode()); Entry localEntry = this.table[indexFor(i, this.table.length)]; for (; localEntry != null; localEntry = localEntry.next) { if (localEntry.hash == i) { java.lang.Object localObject; if (((localObject = localEntry.key) == paramObject) || ((paramObject != null) && (paramObject.equals(localObject)))) { return localEntry; } } } return null; }
由上面代码即可知,hashCode是重要的判断依据,没有重写hashCode,equals表现相等的两个类,它们的hashCode并不相等。
所以会导致containsKey方法返回false,测试代码如下:
包含HashCode的类:
package hashset.and.hashcode; public class ClassWithHashCode { public int i; public boolean equals(Object o) { if (o == this) return true; if (o instanceof ClassWithHashCode) { ClassWithHashCode code = (ClassWithHashCode) o; return code.i == i; } return false; } public int hashCode() { return i * 17 + 37; } }
没有重写hasCode的类:
package hashset.and.hashcode; public class ClassWithoutHashCode { public int i; public boolean equals(Object o) { if (o == this) return true; if (o instanceof ClassWithoutHashCode) { ClassWithoutHashCode code = (ClassWithoutHashCode) o; return code.i == i; } return false; } }
测试类:
package hashset.and.hashcode; import java.util.HashSet; public class Test { /** * @param args */ public static void main(String[] args) { ClassWithHashCode c1 = new ClassWithHashCode(); ClassWithHashCode c2 = new ClassWithHashCode(); c1.i = 0; c2.i = 0; HashSet<ClassWithHashCode> set = new HashSet<ClassWithHashCode>(); set.add(c1); System.out.println(set.contains(c2)); ClassWithoutHashCode co1 = new ClassWithoutHashCode(); ClassWithoutHashCode co2 = new ClassWithoutHashCode(); co1.i = 0; co2.i = 0; HashSet<ClassWithoutHashCode> set1 = new HashSet<ClassWithoutHashCode>(); set1.add(co1); System.out.println(set.contains(co2)); } }
执行的结果为:
true
false
符合预期。证毕。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)