hashCode()与equals()何时需要重写

167 阅读2分钟

一、hashCode()与equals()的作用

equals()容易理解,就是用来比较两个对象的属性是否相等

hashCode()的规定就是:在Java应用程序执行期间,在同一对象上多次调用hashCode()方法时,必须一致地返回相同的整数,前提是对象上equals()比较中所用的信息没有被修改。如果根据equals()方法,两个对象是相等的,那么在两个对象中的每个对象上调用hashCode()方法都必须生成相同的整数结果

说白了hashCode()就是为对象生成一个哈希值,这个哈希值的作用之一就是用来确定这个对象作为key时在HashMap中的下标

二、何时需要重写

首先要知道为什么需要重写:因为这两个函数的默认方法都是根据对象的地址做计算和比较

假设有一个Person类,只含有一个name属性。一般来讲,如果两个Person对象的name属性相同,那么对这两个对象调用equals()应该返回true。但是如果没有重写方法,这两个对象的地址一定不相同,使用equals()比较后会返回false

所以如果要将自定义类作为HashMap的key时,就需要重写,否则会发生内存泄漏

三、如何重写

重写最重要的原则就是:

  • 尽管hashCode()相等,equals()也不一定相等
  • 如果equals()相等,那么hashCode()一定相等
public class Main {
    public static void main(String[] args) {
        HashMap<Person, Integer> map = new HashMap<>();
        Person a = new Person("张三");
        Person b = new Person("张三");
        map.put(a, 1);
        map.put(b, 2);
        System.out.println(map.size());
        System.out.println(a.equals(b));
    }
}
​
class Person {
    public String name;
​
    public Person(String name) {
        this.name = name;
    }
​
    @Override
    public int hashCode() {
        return name.length();
    }
​
    @Override
    public boolean equals(Object other) {
        return name.equals(((Person)other).name);
    }
}

输出结果

1
true

说明b可以覆盖a,如果把两个重写的函数注释掉,输出的结果就会是

2
false

当然这里只是为了方便,简单重写了一下。实际上要考虑的东西还是比较多的,但是就不在这里细说了

而且要注意,如果要将自定义类作为HashMap的key,hashCode()和equals()都需要重写,不能只重写其中一个