Java中创建Point与ArrayList<Integer>的HashMap及重复键判断问题
解决自定义Pair类作为HashMap键时重复键的问题
问题根源在于你自定义的Pair类没有重写Object类的equals()和hashCode()方法。HashMap判断键是否重复的逻辑是:先通过hashCode()获取哈希值,哈希值一致时再调用equals()确认内容是否完全相同。默认的equals()是比较对象引用,hashCode()返回的是对象内存地址相关值,所以哪怕两个Pair的x、y完全一致,只要是不同的对象实例,就会被HashMap当成不同的键。
解决方法就是给Pair类补上这两个方法:
public class Pair { private int x; private int y; public Pair(int x, int y) { this.x = x; this.y = y; } // 访问方法 public int getX() { return x; } public int getY() { return y; } // 重写equals,比较x和y是否都相等 @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Pair pair = (Pair) o; return x == pair.x && y == pair.y; } // 重写hashCode,基于x和y生成哈希值 @Override public int hashCode() { // 用31乘x加y是简单可靠的组合方式,也可以用Java7+的Objects.hash(x,y) return 31 * x + y; } }
修改后,当你创建x、y相同的Pair对象时,map.containsKey(new Pair(x, y))会正确返回true,不会再存入重复的键。
举个使用示例:
HashMap<Pair, ArrayList<Integer>> studentMap = new HashMap<>(); // 往(1,2)坐标添加第一个学生 Pair point1 = new Pair(1, 2); studentMap.put(point1, new ArrayList<>(List.of(1001))); // 往同一个坐标添加第二个学生 Pair point2 = new Pair(1, 2); if (studentMap.containsKey(point2)) { studentMap.get(point2).add(1002); } else { studentMap.put(point2, new ArrayList<>(List.of(1002))); } // 此时map中只会有一个(1,2)键,对应的值包含1001和1002 System.out.println(studentMap.size()); // 输出1
内容的提问来源于stack exchange,提问作者jayant rajput
相关产品推荐
相关产品推荐

