
java 中 hashmap 使用 `equals()` 和 `hashcode()` 判断键的相等性,而原生数组(如 `int[]`)的 `equals()` 方法继承自 `object`,仅比较引用而非内容,导致相同元素的数组被视为不同键。
在使用数组作为 HashMap 的键时,一个常见却极易被忽视的问题是:即使两个 int[] 数组内容完全相同,它们在 HashMap 中也不被视为同一键。这是因为 Java 中的数组类型没有重写 Object.equals() 和 Object.hashCode() 方法——其 equals() 仅做引用比较(即 ==),hashCode() 返回的是对象内存地址的哈希值。
例如:
int[] a = {1, 2, 3};
int[] b = {1, 2, 3};
System.out.println(a.equals(b)); // false —— 内容相同,但引用不同
System.out.println(a == b); // false
System.out.println(Arrays.equals(a, b)); // true —— 需显式调用 Arrays.equals()回到你的代码:
this.coloursHashMap1 = new HashMap(); int[] coord = new int[]{i, j, k}; this.coloursHashMap1.put(coord, cols);
此时 coord 是一个特定对象引用;而在 getColourFromHashInts() 中新建的 new int[]{i,j,k} 是另一个独立对象,与之前 put 时的 coord 引用不同,因此 get() 查找失败,返回 null。
✅ 正确做法:避免直接使用原生数组作为 HashMap 的键。推荐以下任一方案:
方案 1:改用不可变、内容可比的键类型(推荐)
使用 List
Map, int[]> coloursMap = new HashMap<>(); List
key = Arrays.asList(i, j, k); coloursMap.put(key, cols); // 查询时同样构造相同 List int[] result = coloursMap.get(Arrays.asList(i, j, k)); // ✅ 正确命中
方案 2:封装为自定义键类(适合高频或复杂场景)
public final class Coord3D {
public final int x, y, z;
public Coord3D(int x, int y, int z) { this.x = x; this.y = y; this.z = z; }
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Coord3D coord3D = (Coord3D) o;
return x == coord3D.x && y == coord3D.y && z == coord3D.z;
}
@Override
public int hashCode() {
return Objects.hash(x, y, z);
}
}
// 使用方式:
Map map = new HashMap<>();
map.put(new Coord3D(i, j, k), cols);
int[] res = map.get(new Coord3D(i, j, k)); // ✅ ⚠️ 注意事项:
- 不要尝试重写数组的 equals()(无法做到);
- Arrays.hashCode(int[]) 和 Arrays.equals(int[], int[]) 是工具方法,不能改变数组本身的 hashCode()/equals() 行为;
- 若必须用数组,可借助 java.util.Arrays 的静态方法手动标准化(如预计算哈希码并用 Map
> 多层嵌套),但显著增加复杂度,不推荐。
总结:键的语义相等性必须由 equals() + hashCode() 一致保证。原生数组不满足该契约,因此绝不可直接用作 HashMap 键。选择语义清晰、实现正确的键类型(如 List 或自定义不可变类),是保障哈希查找正确性的根本前提。










