为什么重写equals一定重写hashcode

为什么重写equals一定重写hashcode?

​ 因为java某些容器在进行判断对象是否相等之前一般都是先进行hashcode判断hash值是否相等,才会进行equals的判断,所以有“对象相等,hashcode一定相等;而hashcode相等,对象不一定相等。”,原因是哈希表是结合了直接寻址和链式寻址两种方式,如下图:

img

以上图为例,就是将需要加入哈希表的数据首先计算哈希值,其实就是预先按行分组,hashcode就是每组的组号,hashcode相等说明是在同一组,所以可以看出hashcode并不代表所存储对象一定相同。这时就需要我们的equals来进行判断了,如果没有重写equals方法,那么它默认的是比较两个对象的地址值,也就相当于每组组员的编号,所以也有“equals相等,hashcode一定相等。”,equals都相等了,那就代表就是同一个对象了,那你的组号肯定也就相等了。

​ 那么言归正传,为什么重写equals就一定要重写hashcode呢?因为java的某些容器(如HashSet)在添加对象的时候,会先调用hashcode来判断,如果hashcode值不一样就直接判断为两个不一样的对象进行存储,而在某些情况下,如:

Student student1 = new Student(1  , "李青");
Student student2 = new Student(1  , "李青");
System.out.println(student1.equals(student2));//true

我们重写了equals方法:

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    Student student = (Student) o;
    if(this.id != student.getId() || this.name != student.name) return false;
    return true;
}

希望表达的意思是,学生类的学号与名字相同那么这个学生就是同一个人,我们放入容器中时也希望容器只存储一个对象,但因为比较的时候是先比较的hashcode,所以一上来就判断为了两个对象,然后就分别存储进了容器中,这也就产生了逻辑上的歧义,我就是一个人,你为什么要存两条我的记录呢?这也就违背了“equals相等,hashcode一定相等。”的规则,当然要记住规则不是原因,原因才是规则产生的前提条件。不要别人一问你为什么重写equals就一定要重写hashcode,你就回答个因为规定如此就好了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值