面试:为什么重写equals()就一定要重写hashcode()方法

张开发
2026/4/15 15:25:37 15 分钟阅读

分享文章

面试:为什么重写equals()就一定要重写hashcode()方法
先记住官方的黄金约定必须遵守(1) 两个对象用 equals () 判断相等它们的 hashCode () 返回值必须相同(2) 两个对象 hashCode () 相同equals () 不一定相等哈希冲突(3) 如果违反这个约定基于哈希表的集合会完全失效HashMap、HashSet、Hashtable1. 底层原理哈希集合是怎么工作的以最常用的 HashSet / HashMap 为例它们存储数据分两步第一步算 hashCode → 决定对象存在哪个 “桶” 里第二步用 equals 比较 → 在桶里找到完全相同的对象核心逻辑集合默认认为equals 相等 → hashCode 一定相等2.举例说明publicclassUser{privateStringid;publicUser(Stringid){this.idid;}// 只重写equalsid相同就是同一个用户Overridepublicbooleanequals(Objecto){if(thiso)returntrue;if(onull||getClass()!o.getClass())returnfalse;Useruser(User)o;returnid.equals(user.id);}// 故意不写 hashCode() !!!}publicclassTest{publicstaticvoidmain(String[]args){Useru1newUser(1001);Useru2newUser(1001);// 1. equals 判断true我们认为是同一个对象System.out.println(u1.equals(u2));// 2. 存入 HashSetHashSetUsersetnewHashSet();set.add(u1);set.add(u2);// 3. 预期集合大小1重复元素不能存// 实际大小2BUG出现了System.out.println(set.size());}}为什么会这样u1 和 u2 的equals相等 → 本应该是同一个对象但没有重写 hashCode用的是 Object 默认的 hashCode内存地址计算两个对象的hashCode 不同 → 被放进了 HashSet 的不同桶里集合根本不会去调用 equals → 错误认为是两个不同对象结果HashSet 去重失效HashMap 键值对重复业务直接出错3.总结为什么必须一起重写(1) 遵守 Java 契约这是 Java 语言的强制规范(2) 保证哈希集合正常工作HashMap/HashSet/Hashtable 完全依赖这两个方法(3)避免致命 BUG不重写会导致集合去重、查找、存储全部失效4. 正确写法Overridepublicbooleanequals(Objecto){if(thiso)returntrue;if(onull||getClass()!o.getClass())returnfalse;Useruser(User)o;returnObjects.equals(id,user.id);// 比较id}OverridepublicinthashCode(){returnObjects.hash(id);// 用id计算哈希值}

更多文章