为什么重写equals时要重写hashcode

135 阅读2分钟

hashcode:提高具有哈希结构的容器的效率!哈希值主要根据地址号来的,但不能完全将哈希值等价于地址。

  • 相同的两个对象,hashcode值一定相同;但hashcode值相同,对象确可能不同(杂凑算法导致的碰撞问题)。
  • 在hashSet的add方法时,如果待添加的对象的hashcode值在hashSet中没有,hashSet就默认对象没有重复出现,就直接添加;如果有相同的就调用equals(因为hashcode值相同,对象确可能不同),所以说hashcode只是缩小了查找成本,省去了hashcode都不同时候的成本。
为什么重写equals要重写hashcode

都不重写的时候:

两个不同的对象作为key;这2个key,在Map计算的时候,可能数组下标就不一致,就算数据下标碰巧一致,根据前面,最后equals比较的时候也不可能相等(很显然,这是2个对象,在堆上的地址必定不一样)

重写了equals方法后:

两个不同的对象因为重写方法的原因变得相同了,这个时候Map调用add时,应该只能进去一个,但是add方法会首先根据hashcode进行判断,对于没有重写的hashcode,这两个对象是不同的,所以两个都进去了。所以需要将hashcode方法进行重写。

代码解析:根据狗的名字来重写equals和hashcode,这个时候就没有问题。但只重写equals,最后hashMap的size=2,因为hashcode不同。idea重写equals时会自动带上hashcode的重写。

public class ag {
    public static void main(String[] args) throws Exception {
        dog dog1 = new dog("大黄");
        dog dog2 = new dog("大黄");
        HashMap hashMap = new HashMap();
        hashMap.put(dog1,null);
        hashMap.put(dog2,null);
        System.out.println(hashMap.size());//1
    }
}
class dog{
    private String name;
​
    public String getName() {
        return name;
    }
​
    public dog(String name) {
        this.name = name;
    }
​
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof dog)) return false;
        dog dog = (dog) o;
        return Objects.equals(getName(), dog.getName());
    }
    @Override
    public int hashCode() {
        return Objects.hash(getName());
    }
}

\