为什么重写了equals()方法还要重写hashCode()方法

== 比较

java中的数据类型,可分为两类:

1.基本数据类型,也称原始数据类型

byte,short,char,int,long,float,double,boolean
他们之间的比较,应用双等号(==),比较的是他们的值。

2.引用类型(类、接口、数组)

当他们用(==)进行比较的时候,比较的是他们在内存中的存放地址,所以,除非是同一个new出来的对象,他们的比较后的结果为true,否则比较后结果为false。对象是放在堆中的,栈中存放的是对象的引用(地址)。先看下虚拟机内存图和代码:

equals 比较

  • equals是object的方法,所以每个类都有equals方法,区别在于是否重写了该方法;

  • 很明显Object定义的是对两个对象的地址值进行的比较

		//equals 源码
		public boolean equals(Object obj) {
		    return (this == obj);
		}
  • String 类重写了equals()方法,重写后比较的是内容是否一致.
public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

hash比价

hash比较其实就是计算一个对象的hash值

hash算法的大致过程:

  • 由键key得出hashCode
  • 由hashCode算出hash值
  • 由hash算出于数组中的下标
    在这里插入图片描述
  • 1-我们知道无论是键还是值,都应该是一个对象,不同的对象具有不同的存储地址,hashCode得到的哈希值就是根据对象的地址转化而来的。
  • 2:在hashmap中,对hashcode方法进行了重写,重写的时候用到了hash算法,即把hashcode的高16位与低16位进行异或运算,得到hash值。

  • 3:把hash值与数组长度减一进行“与”运算得到下标。(这里需要注意的是,因为数组的长度始终是2的次方幂,这里的与运算,就相当于给length-1取模运算)

为什么在重写equals方法的时候要重写hashcode的方法?

我们知道判断的时候先根据hashcode进行的判断,相同的情况下再根据equals()方法进行判断。如果只重写了equals方法,而不重写hashcode的方法,会造成hashcode的值不同,而equals()方法判断出来的结果为true。

在Java中的一些容器中,不允许有两个完全相同的对象,插入的时候,如果判断相同则会进行覆盖。这时候如果只重写了equals()的方法,而不重写hashcode的方法,Object中hashcode是根据对象的存储地址转换而形成的一个哈希值。这时候就有可能因为没有重写hashcode方法,造成相同的对象散列到不同的位置而造成对象的不能覆盖的问题。

总结:
  • 在特殊容器中,比如HashMap中,它是链表+数组的结构,链表是key的hash值来确定的位置
  • 不重写hashcode的方法,会造成hashcode的值不同,而equals()方法判断出来的结果为true的数据放在不同的节点位置

在这里插入图片描述

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值