Java 必看:如何正确重写 hashCode() 和 equals() 方法? [TOC]( Java 必看如何正确重写 hashCode() 和 equals() 方法)The Begin点点关注收藏不迷路⬇ ⬇ 底部 ⬇ ⬇一、先记住 4 条黄金规范必须遵守两个对象 equals 为 true → hashCode 必须相同hashCode 相同 → equals 不一定为 true哈希冲突参与equals比较的属性必须全部参与 hashCode 计算只要对象内容没变hashCode必须始终返回相同值不遵守 → HashSet/HashMap 无法去重出现严重 Bug二、最推荐写法Objects 工具类JDK 71. 通用模板直接复制改属性名即可importjava.util.Objects;publicclass类名{// 你的成员变量private类型 属性1;private类型 属性2;// 重写开始 Overridepublicbooleanequals(Objecto){// 1. 同一个对象直接返回 trueif(thiso)returntrue;// 2. 为null 或 类型不同返回 falseif(onull||getClass()!o.getClass())returnfalse;// 3. 强制类型转换类名 其他对象(类名)o;// 4. 比较【所有关键业务属性】决定是否重复的字段returnObjects.equals(属性1,其他对象.属性1)Objects.equals(属性2,其他对象.属性2);}OverridepublicinthashCode(){// 必须和 equals 里的属性完全一致returnObjects.hash(属性1,属性2);}// 重写结束 }三、完整实战示例最常用以User对象为例根据id username去重importjava.util.Objects;publicclassUser{privateLongid;privateStringusername;privateIntegerage;// 假设 age 不参与去重// 构造、get、set 省略...// 核心重写 Overridepublicbooleanequals(Objecto){if(thiso)returntrue;// 判断类型安全if(onull||getClass()!o.getClass())returnfalse;Useruser(User)o;// 只比较【业务唯一】的字段id usernamereturnObjects.equals(id,user.id)Objects.equals(username,user.username);}OverridepublicinthashCode(){// 必须和 equals 完全一致returnObjects.hash(id,username);}}效果new User(1, 张三, 20)new User(1, 张三, 30)放入 HashSet 会被判定为重复元素成功去重四、为什么不能用 IDE 自动生成可以用但要懂IntelliJ IDEA / Eclipse 都能一键生成完全可以用生成快捷键WindowsAlt InsertMacCmd N选择equals() and hashCode()→ 勾选参与去重的字段 → 自动生成生成的代码和我上面给的完全一致非常标准。五、最常见的 3 个错误一定要避开错误 1equals 和 hashCode 使用的属性不一致// ❌ 错误示范equals 用 id hashCode 用 username → 去重失效错误 2只重写 equals不重写 hashCode// ❌ 致命错误// HashSet 会先判断 hashCode不同就直接插入根本不会走 equals错误 3使用可变值参与 hashCode比如用一个会被修改的变量计算 hashCode→ 对象存入后值变了 → hashCode 变了 → 再也找不到这个元素六、一句话总结面试必背equals 决定两个对象是否“内容相等”hashCode 决定对象在哈希表中的存储位置HashSet 去重规则hashCode 相同 equals 为 true重写原则参与 equals 的属性必须全部参与 hashCodeThe End点点关注收藏不迷路⬆ ⬆ 顶部 ⬆ ⬆