为什么要重写hashcode和equals方法?

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/world6/article/details/52127510

为什么要重写hashcode和equals方法?


相信很多小伙伴被这个问题给困扰很久了,下面我就给大家详细说一下我的理解吧~



因为默认的equals方法是Object的方法,比较的是内存地址;而默认的hashcode方法返回的是对象的内存地址转换成的一个整数,实际上指的的也是内存,两个方法可以理解为比较的都是内存地址,这在实际开发的过程中在hashmap或者hashset里如果不重写的hashcode和equals方法的话会导致我们存对象的时候,把对象存进去了,取的时候却取不到想要的对象,这时候就需要重写这两个方法了,一般可以根据业务的需求来重写;


如果对象有名字和年龄这两个属性的话,最常见重写hashcode的方法是采用hash算法:
     int hash=a*b+age/name;再将hash值返回。 


重写equals方法是认为在名字和年龄不为空的情况下,名字相等并且年龄也相等,那么就认为这是同一个对象。重写了hashcode和equals方法后我们就可以取得我们想要的值了,这样做保证了键值的唯一性,更有利于程序稳定


因为重写了hashcode和equals方法可以迅速的在hashmap中找到键的位置;

Hashmap是通过hashcode来确定元素的下标的,具体的代码如下;
int hash = hash(key.hashcode());  通过算出来的hash值,还有hashmap表的长度,可以确定元素在hashmap表中的下标,但是这种hash算法过于简单,会导致很多冲突发生,因为不同的key可以算出相同的hashcode,所以每个下标对对应的链表位置上会有很多的Entry对象,这时候就会通过key的equals方法在对应位置的链表中找到需要的元素,所以这个时候就需要重写equals方法,Hashmap的key可以是任何类型的对象,例如User这种对象,为了保证两个具有相同属性的user的hashcode相同,我们就需要改写hashcode方法,比方把hashcode值的计算与User对象的id关联起来,那么只要user对象拥有相同id,那么他们的hashcode也能保持一致了,这样就可以找到在hashmap数组中的位置了。如果这个位置上有多个元素,还需要用key的equals方法在对应位置的链表中找到需要的元素,所以只改写了hashcode方法是不够的,equals方法也是需要改写滴~当然啦,按正常思维逻辑,equals方法一般都会根据实际的业务内容来定义,例如根据user对象的id来判断两个user是否相等。 

对于两个对象,Java要求如下:

equals()相等,hashcode()一定相等;

quals()不等,hashcode()可能相等,也可能不等;

hashcode()不等,一定能推出equals()也不等;

hashcode()相等,equals()可能相等,也可能不等。


如果不重写hashcode和equals方法的话,放入相同的key时(特殊情况下),就不知道取哪一个。


举个例子:我们创建两个匿名的对象,当做key;new Person(“张三”); new Person(“张三”);


此时我们存放两个匿名对象是没有问题的,但取的这个作为key的匿名对象的时候就取不到了。输出结果会是null;


总结:重写hashcode方法和equals方法是为了程序运行更加稳定更加友好!


1.重写hashcode是为了保证相同的对象会有相同的hashcode;

2.重写equals是为了保证在发生冲突的情况下取得到Entry对象(也可以理解是key或是元素);


此文是一年前写的,当时可能理解得还不太正确,总结里的两点当时说得没错,但是不太好理解;

重写hashcode和equals方法的原因有两个:

1、因为 在hashmap中不论是put还是get操作会用到这两个方法;

2、Java规范的约定,在集合类中需要重写这两个方法;

我这篇博客说得比较清楚;点这里


我的博客即将搬运同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan 


展开阅读全文

没有更多推荐了,返回首页