Java HashMap自定义Triple键查找失败(引用匹配而非值匹配)如何修复?
嗨,这个问题我太熟了!Java里用自定义类当HashMap的键,必须重写equals()和hashCode()方法,不然HashMap就会默认用对象的引用地址来判断相等,自然找不到你认为“值相同”的键啦。
问题根源
HashMap判断两个键是否相等的规则是:
- 两个对象的
hashCode()返回值必须相等 - 同时调用
equals()方法返回true
而你当前的Triple类没有重写这两个方法,用的是Object类默认实现:
- 默认
hashCode()返回的是对象的内存地址哈希值 - 默认
equals()只是比较两个对象的引用是否相同
所以哪怕两个Triple对象的kid、x、y完全一样,只要是不同的实例,HashMap就会把它们当成不同的键,导致查找失败。
修复方案
给Triple类重写equals()和hashCode()方法,基于kid、x、y这三个核心属性来实现:
import java.util.Objects; public class Triple{ public int kid; public int x; public int y; public Triple(int a, int b, int c){ kid=a; x=b; y=c; } public Triple(Triple notAcopy, int next, boolean reverse){ kid=notAcopy.kid; x=notAcopy.x + next; if (reverse) y=notAcopy.y-next; else y=notAcopy.y+next; } // 重写equals方法,基于三个属性判断对象相等 @Override public boolean equals(Object o) { if (this == o) return true; // 同一个引用直接判定相等 if (o == null || getClass() != o.getClass()) return false; // 类型不同或为null直接判定不等 Triple triple = (Triple) o; // 逐一比较三个核心属性的值 return kid == triple.kid && x == triple.x && y == triple.y; } // 重写hashCode方法,基于三个属性生成哈希值 @Override public int hashCode() { // 用Objects工具类生成组合哈希值,简单且避免手动计算的错误 return Objects.hash(kid, x, y); } }
为什么这样修复?
- hashCode()的作用:HashMap会根据键的hashCode值确定存储的桶位置,只有hashCode相同的对象才会被放到同一个桶里。如果两个值相同的Triple对象hashCode不同,HashMap会直接去不同的桶查找,自然找不到目标键。
- equals()的作用:当多个对象hashCode相同时(哈希碰撞),HashMap会在桶里逐个调用equals方法比较,只有equals返回true的对象才会被认为是同一个键。
这两个方法必须同时重写,不能只写一个,否则会出现各种异常问题(比如明明equals相同但hashCode不同导致找不到;或者hashCode相同但equals不同导致HashMap出现重复键)。
这样修改之后,只要两个Triple对象的kid、x、y值完全相同,HashMap就会把它们当成同一个键,你的b和d就会返回true啦。
内容的提问来源于stack exchange,提问作者BAMF4bacon
相关产品推荐
相关产品推荐

