必须同时重写hashcode和equals方法的原因

2020-08-01 15:06:49 浏览数 (3)

在不重写这两个方法时,hashcode是内存地址计算出的值,equals是用==来判断是否相同,也就是根据内存地址判断是不是相同对象。

假如我现在在开发中有一个person类,他有一些属性 如:姓名 年龄 住址。而我逻辑上需要当姓名和年龄都相同时,就认为这是同一个人,也就是同一个对象。那么肯定要重写它的equals方法

代码语言:javascript复制
class Person{
    String name;
    String sex;
    String address;
    //getter setter
    @Override
    public boolean equals(Person p){
        if(this == p) return true;
        return (p.getName() == this.name  && p.getSex() == this.sex);
    }
}

在没有重写hashcode时,对于两个姓名、年龄都相同的person对象,hashcode肯定不同,但是equals却返回true。这里就违反了关于hashcode的约定,也会产生许多问题。

假如当我把很多person对象放入一个hashset集合中时,需要根据姓名和年龄去重。明明两个对象的姓名、年龄相同了,应该被过滤掉,但是由于在add时,两个对象的hash值不同,则不会被去重。就发生了我们认为应该被去重,但是却没有的情况,违背了设计初衷。然而在根据equals需要的属性重写hashcode方法时,保证了equals相同,hashcode一定相同,就可以避免这种错误。

代码语言:javascript复制
class Person{
    String name;
    String sex;
    String address;

    //getter setter

    @Override
    public boolean equals(Person p){
        if(this == p) return true;
        return (p.getName() == this.name  && p.getSex() == this.sex);
    }

    @Override
    public int hashCode() {
        return name.hashCode()   sex.hashCode();
    }
}

hash的好处:

假如set集合已经有一万个对象,需要挨个比较的话肯定效率特别低,而hash值就像一张每个人都有的银行卡号,在于众多对象进行比较时,只需要去判断我这个对象的hash值有没有在set中,而不需要去顺序对比,效率很高!

所以两个方法要同时重写的目的就是 要保证equals方法如果返回相同,则hashcode值一定相同

1 人点赞