为什么重写equals()方法时一定要重写hashCode()方法??

原因总结 :

重要的理论基础:
1、 每个对象都有自己的hashCode()方法,产生哈希值,两个对象的哈希值是可能重复的,这就是哈希冲突,一般通过链表和线性探索来解决哈希冲突问题。
2、对象存储咋内存中的地址是通过hash来确定的。

  • 1、重写equals()方法的初衷:我们一般在自定义的实体类中重写equals()方法和hashCode()方法来使得属性值完全相等的两个对象指向同一个内存地址
  • 2、当我们需要将对象存入集合是,比如Map集合,需要先判断这个对象是否已经存在了,那么判断的依据是什么呢?不是equals()比较结果,而是hash值,这样判断效率较高,
  • 如果发现当前对象的hash值已经存在集合中了就不会再将这个对象存在集合中,否则就存入
  • 3、对象存储内存中的地址是通过hash值来确定的。
  • 4、假设我们值重写了equals()方法 使得 x.equals(y)==true 旨在说明x和y是同一个对象,应当被存储在同一个内存地址。但事实并非如此:
  • 没有重写hashCode()方法就更改不了hash值,就没办法使得x,y 指向同一个内存地址,也就是说,在内存中,这依然是两个不同的独立的对象!!
  • 5、那么接下来,我们假设map集合中已经存放了x,我们想要向集合map中添加y,就会添加成功,因为他们的hash值并不相同,会被认为是不同的对象。这无疑是跟map集合的本意,以及程序员的本意是相违背的。

代码演示说明:

自定义两个内部类 : Student 不充写hashCode()方法以及equals()方法
Teacher两个方法都重写
可以看到:重写两个方法后,equals()方法和hashCode()的结果都指示着两个属性完全一样的对象隶属于同一个对象,是我们想要的结果。


```public class Demo02 {
    static class Student{
        String name;
        Integer age;

        public Student() {
        }

        public Student(String name, Integer age) {
            this.name = name;
            this.age = age;
        }
    }

    static class Teacher{
        String name;
        Integer age;

        public Teacher() {
        }

        public Teacher(String name, Integer age) {
            this.name = name;
            this.age = age;
        }
        //重写equals()和hashCode()
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Teacher teacher = (Teacher) o;
            return Objects.equals(name, teacher.name) && Objects.equals(age, teacher.age);
        }

        @Override
        public int hashCode() {
            return Objects.hash(name, age);
        }
    }
    public static void main(String[] args) {
        Student student1 = new Student("张三",12);
        Student student2 = new Student("张三",12);
        System.out.println("没有重写equals()方法时:"+ student1.equals(student2));//两个对象地址不相同,所以两个对象并不相等
        //哈希值也不相等
        System.out.println("student1的hash值:"+student1.hashCode());
        System.out.println("student2的hash值:"+student2.hashCode());


        //重写方法之后:预测hash值应该相同——预测结果正确
        Teacher teacher1 =new Teacher("张三",12);
        Teacher teacher2 =new Teacher("张三",12);
        System.out.println("重写equals()方法时:"+ teacher1.equals(teacher2));//true

        System.out.println("teacher1的hash值:"+teacher1.hashCode());//24022532
        System.out.println("teacher2的hash值:"+teacher2.hashCode());//24022532
    }

}

假如将Teacher中重写的hashCode()方法删掉:再查看两个对象的hash值:即使equals()方法判断两个对象相等,他们的hash值也不会相等。


        //假如不重写 hashCode()方法
        System.out.println("重写equals()方法时:"+ teacher1.equals(teacher2));//true

        System.out.println("teacher1的hash值:"+teacher1.hashCode());//1078694789
        System.out.println("teacher2的hash值:"+teacher2.hashCode());//1831932724


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值