Java PMD规则要求重写equals必重写hashCode:原因及实现方法
嘿,这个问题问到点子上了——这可是Java开发里一个高频踩坑点,我给你详细唠唠:
关于Java中同时重写
equals()和hashCode()的原因及实现示例 为什么必须同时重写equals()和hashCode()?
这得从Java哈希集合的核心逻辑说起,比如我们常用的HashMap、HashSet这类容器,它们的工作严重依赖hashCode():
- 当你把对象放进这些容器时,JVM会先调用
hashCode()算出哈希值,以此确定对象该放在哪个“哈希桶”里; - 之后要查找、删除这个对象时,也是先通过
hashCode()定位到对应的桶,再在桶里用equals()逐个比较。
Java官方对这两个方法有个硬性契约:如果两个对象通过equals()判断为相等,那么它们的hashCode()必须返回相同的值。反过来,hashCode()相同的对象equals()可以不等(这只会引发哈希冲突,影响一点性能而已)。
要是你只重写equals()却不管hashCode(),就会出现离谱的情况:两个逻辑上完全相等的对象(equals()返回true),但hashCode()结果不一样。这时候把它们放进HashMap,会被当成两个完全独立的键——你存进去一个后,用另一个相等的对象去查,根本找不到,完全违背了我们对集合的预期。
你的MyClass应该怎么实现hashCode()?
因为你的equals()方法完全是基于id属性来判断相等的,所以hashCode()必须和id绑定,确保所有equals()相等的对象,hashCode()结果绝对一致。
最简单直接的实现就是直接返回id本身——毕竟id是int类型,本身就可以作为有效的哈希值:
@Override public int hashCode() { return id; }
如果想更规范、或者为未来扩展属性留余地(比如以后给MyClass加其他参与equals()判断的属性),也可以用Java提供的工具方法:
// 用Integer的工具方法,专门处理int类型的哈希生成 @Override public int hashCode() { return Integer.hashCode(id); } // 或者用Objects.hash(),适合多属性的场景,扩展性拉满 @Override public int hashCode() { return Objects.hash(id); }
这几种实现都完美符合Java的契约要求,只要两个MyClass对象的id相等,它们的hashCode()就一定相同,和equals()的逻辑完全匹配。
内容的提问来源于stack exchange,提问作者J.ty
相关产品推荐
相关产品推荐

