HashMap无法正确识别键:为何传入数组与单独传参取值结果不同?
问题核心:数组作为HashMap键的引用匹配特性
你遇到的问题本质是Java数组的equals()和hashCode()方法是基于对象引用而非内容比较,这和HashMap的工作机制直接相关:
HashMap的键匹配逻辑
HashMap查找键时,会先比较两个键的hashCode()是否相等,再调用equals()方法确认。对于数组来说:hashCode()返回的是对象的内存地址哈希值equals()直接比较两个数组的引用是否指向同一内存地址
对应你的代码场景
- 存入HashMap的
coord是一个特定的数组对象,有唯一的内存引用 getColourFromHashArr传入的是同一个数组对象,引用完全匹配,所以能正确找到值getColourFromHashInts里新建的new int[]{i,j,k}是全新的数组对象,哪怕内容和原数组一致,内存引用也完全不同,HashMap会判定这是两个不同的键,因此返回null
- 存入HashMap的
可行的解决办法
用自定义类封装坐标:创建一个包含i、j、k三个属性的类,重写
equals()和hashCode()方法,基于三个属性的内容计算哈希和判断相等class Coord { private int i; private int j; private int k; public Coord(int i, int j, int k) { this.i = i; this.j = j; this.k = k; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Coord coord = (Coord) o; return i == coord.i && j == coord.j && k == coord.k; } @Override public int hashCode() { return Objects.hash(i, j, k); } }之后用
HashMap<Coord, int[]>替换原集合即可。用List
代替数组 :Java的List接口实现类(比如ArrayList)的equals()和hashCode()是基于元素内容的,直接用List<Integer>作为键就能按内容匹配:// 存入时 List<Integer> coord = Arrays.asList(i, j, k); coloursHashMap1.put(coord, cols); // 获取时 public int[] getColourFromHashInts(int i, int j, int k){ List<Integer> coord = Arrays.asList(i, j, k); return coloursHashMap1.get(coord); }自定义Map的键比较逻辑(不推荐):如果一定要用数组作为键,可以使用
TreeMap并传入自定义的Comparator<int[]>,基于数组内容比较:TreeMap<int[], int[]> coloursHashMap1 = new TreeMap<>(Arrays::compare);但这种方式会改变Map的排序逻辑,且性能不如前两种方案,仅作特殊场景备选。
内容的提问来源于stack exchange,提问作者James Marshmallow
相关产品推荐
相关产品推荐

