关于为什么要重写hashCode()方法和equals()方法及如何重写

开发者福利!热门AI工具限时免费用 购周边即赠Coding Plan Lite,Claude Code、Cursor等20+工具畅享,效率翻倍! 阅读详情

我想写的问题有三个:

1、首先我们为什么需要重写hashCode()方法和equals()方法

2、在什么情况下需要重写hashCode()方法和equals()方法

3、如何重写这两个方法

*********************************************************************

第一个问题:为什么需要重写hashCode()方法和equals()方法

    Java中的超类Object类中定义的equals()方法是用来比较两个引用所指向的对象的内存地址是否一致

Object类中equals()方法的源码

public boolean equals(Object obj) {

       return (this == obj);

}

********************************************************************

Object类中的hashCode()方法,用native关键字修饰,说明这个方法是个原生函数,也就说这个方法的实现不是用java语言实现的,是使用c/c++实现的,并且被编译成了DLL,由java去调用,jdk源码中不包含。对于不同的平台它们是不同的,java在不同的操作系统中调用不同的native方法实现对操作系统的访问,因为java语言不能直接访问操作系统底层,因为它没有指针。

这种方法调用的过程:

1、在java中申明native方法,然后编译

2、用javah产生一个  .h  文件

3、写一个 .cpp文件实现native导出方法,其中需要包含第二步产生的.h文件(其中又包含了jdk带的jni.h文件);

4、将.cpp文件编译成动态链接库文件

5、在java中用System.loadLibrary()文件加载第四步产生的动态链接库文件,然后这个navite方法就可被访问了

Java的API文档对hashCode()方法做了详细的说明,这也是我们重写hashCode()方法时的原则【Object类】

重点要注意的是:

a.  在java应用程序运行时,无论何时多次调用同一个对象时的hsahCode()方法,这个对象的hashCode()方法的返回值必须是相同的一个int值

b.  如果两个对象equals()返回值为true,则他们的hashCode()也必须返回相同的int值

c.  如果两个对象equals()返回值为false,则他们的hashCode()返回值也必须不同

public native int hashCode();

 

现在到了说正题了,为什么要重写

我们在定义类时,我们经常会希望两个不同对象的某些属性值相同时就认为他们相同,所以我们要重写equals()方法,按照原则,我们重写了equals()方法,也要重写hashCode()方法,要保证上面所述的b,c原则;所以java中的很多类都重写了这两个方法,例如String类,包装类

 

4、第二个问题:在什么情况下需要重写hashCode()方法和equals()方法

当我们自定义的一个类,想要把它的实例保存在集合中时,我们就需要重写这两个方法;集合(Collection)有两个类,一个是List,一个是Set

List:集合中的元素是有序的,可以重复的

Set:无序,不可重复的

以HashSet来说明:

HashSet存放元素时,根据元素的hashCode值快速找到要存储的位置,如果这个位置有元素,两个对象通过equals()比较,如果返回值为true,则不放入;如果返回值为false,则这个时候会以链表的形式在同一个位置上存放两个元素,这会使得HashSet的性能降低,因为不能快速定位了。还有一种情况就是两个对象的hashCode()返回值不同,但是equals()返回true,这个时候HashSet会把这两个对象都存进去,这就和Set集合不重复的规则相悖了;所以,我们重写了equals()方法时,要按照b,c规则重写hashCode()方法!

 

5、第三个问题:如何重写这两个方法

 

我写了一个例子,大家可以看一下

*******************************************************************************

package cn.hashCode.jing;

 

/**

 *定义一个Ponint测试类,用来测试Set集合保存元素的方式中

 *hashCode()方法和equals()方法对Set集合保存元素影响

 *

 */

public final class Point {

 

    private int x;

    private int y;

    public Point(){

       super();

    }

    public Point(int x,int y){

       this.x=x;

       this.y=y;

    }

    public int getX() {

       return x;

    }

    public void setX(int x) {

       this.x = x;

    }

    public int getY() {

       return y;

    }

    public void setY(int y) {

       this.y = y;

    }

    @Override

    public boolean equals(Object obj){

       if(this==obj){

           return true;

       }

       if(obj!=null && obj.getClass()==Point.class){

           Pointpo=(Point)obj;

           if(this.x==po.x && this.y==po.y){

              return true;

           }

       }

       return false;

    }

    @Override

    public int hashCode(){

       return 7*x+31*y;

    }

/*以下是自动生成的

    @Override

    publicboolean equals(Object obj) {

       if(this == obj)

           returntrue;

       if(obj == null)

           returnfalse;

       if(getClass() != obj.getClass())

           returnfalse;

       Pointother = (Point) obj;

       if(x != other.x)

           returnfalse;

       if(y != other.y)

           returnfalse;

       returntrue;

    }

    @Override

    publicint hashCode() {

       finalint prime = 31;

       intresult = 1;

       result= prime * result + x;

       result= prime * result + y;

       returnresult;

    }*/

    public String toString(){

       return x+","+y+" ";

    }

 

}

package cn.hashCode.jing;

 

import java.util.HashSet;

 

public class TestHashSet {

 

    public static void main(String[] args) {

       HashSet<Point>hs=new HashSet<Point>();

       Pointp1=new Point(3,4);

       Pointp2=new Point(6,4);

       Pointp3=new Point(10,7);

       Pointp4=new Point(8,9);

       Pointp5=new Point(3,4);

       hs.add(p1);

       hs.add(p2);

       hs.add(p3);

       hs.add(p4);

       hs.add(p5);

       System.out.println(p1.equals(p5));

       System.out.println(p1.hashCode());

       System.out.println(p5.hashCode());

       System.out.println(hs);

}

}

结果:true

145

145

[3,4 , 6,4 , 10,7 ,8,9 ]

 

可以自己试一下,hashCode()返回值相等,equals()返回false;和hashCode()返回值不相等,equals()返回值为true;都会出现什么情况

【关于DLL文件】http://wapbaike.baidu.com/view/230750.htm?adapt=1&fr=aladdin

【为什么重写】  http://m.blog.csdn.net/article/details?id=8197508(这篇讲的
为什么重写equals()方法时,必须要求重写hashCode()方法 equals() 方法 hashcode() 方法是 java.lang.Object 类的两个重要的方法,Java中多数类都会重写 Object 类的 equals() 方法。 在实际应用中,如果我们自定义的类需要进行比较操作,就一定也需要重写 equals() 方法。那么为什么重写 equals()方法时,必须要求重写 hashCode() 方法呢? 首先, equals() 方法 h... 阅读详情

相关推荐

【Java】如何重写hashCode()equals()方法

文章目录1. 如何重写hashCode()方法2. 如何重写equals()方法 如之前提到的对hashCode()的分析: 【Java】hashCode特性、算法作用 例子代码中的类: class Worker { private String name; private int age; private double salary; //...略 } 1. 如何重写hashCode...

Hello, New World! 2508

hashSet重写-重复equals方法-实现定向去重

1.hashSet重写-重复equals方法-实现定向去重 一.出现的问题是: 想通过SET来实现对类中重复类进行去除,但是类中有些字段重复就认定该类型为重复类型 想要变成:上面两个字段重复,便认为以上类型重复 解决方案: 通过SET去除重复: 1.需要重写hashSet里的方法: 学习hashSet的方法过程: hashSet判断两个对象是否相等,会进行比较has...

无名小辈 4583

DJI MobileSDK运行实例代码教程(保姆级)坑踩完了

其中比较重要的是PackageName也就是我们应用的包名,在这里我们可以直接使用官方文档中的包名,com.dji.ImportSDKDemo,appname为:ImportSDKDemo,其他的可以随意。在C盘中根据路径先找到 “用户/admin/.gradle”下的.gradle文件夹,然后依次打开wrapper/dists文件夹,找到我们刚刚要下载的gradle版本名的文件夹。在Androidstudio中打开,选在打开项目选择文件下载后的保存路径(解压之后的),在打开项目后会自动下载gradle。

k1121568的博客 2831

为什么重写hashCode()equals()

从源码的角度,介绍hashCode()equals()函数的作用,解释为什么需要重写,什么时候需要重写,具体应该怎么重写

LYQ20010417的博客 4890

重写HashCode与equal方法

一、为什么重写hashCode与equal 1.判断两个或多个引用类型的值相等的条件: 1.1 条件1:引用类型的地址相等(充分而不必要); 1.2 条件2:引用类型的值相等(充分必要) 2.引用类型数据: 除了8种基本数据类型以外的数据; 引用类型一般都是通过new关键字创建对象,然后把这个对象赋予给相应的变量,最常用的引用类型是String类型,它也比较特殊,可以直接通过关键字new来创建对象,也可以通过字符串直接赋值,比如: Stri...

zyh661120的博客 5204

为什么要同时重写hashcode()equals()方法

1. 重写equals方法是为了比较两个不同对象的值是否相等; 2. 重写hashCode是为了让同一个Class对象的两个具有相同值的对象的Hash值相等; 3. 同时重写hashCode()equals()是为了满足HashSet、HashMap等此类集合的相同对象的不重复存储;

大龄烤红薯的博客 754

重写hashCode也得重写方法

这是一个非常经典的问题,我们先从运算符“==”来说明一下。

s44359487yad的博客 1534

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

如果涉及使用对象作为key,那么key的对象都必须实现hashCodeequals方法hashCodeequals方法持续自根类Object,若是你用自定义的类算作key的话,就需要同时覆写equals办法hashCode方法,因为我们java的集合中判断两个对象是否相等,是根据hashCodeequals这个俩个方法。规则是先判断两个对象的hashCode是否相等,如果不相等,认为两个对

sixingmiyi39473的博客 7834

怎么重写equals()方法hashCode()方法

equals()

qq_63882368的博客 1688

为什么重写equals()就要重写hashCode()

文章目录一、前言二、hashCode()方法三、equals()方法四、hashCode()equals()4.1 不会创建“类对应的散列表”的情况4.2 会创建“类对应的散列表”的情况4.2.1 Set无法去重问题4.2.2 哈希冲突问题4.2.3 equals()hashCode()完全对应4.2.4 进一步解释为什么重写equals()就要重写hashCode()?五、重写hashCode()的目标六、面试金手指6.1 为什么重写equals()一定要重写hashCode()6.1.1 不会创

毛毛的专栏 3998

HashSet底层原理,为什么重写hashCode()equals()重写equals()为什么一定要重写hashCode()

文章目录前言一、重写hashCode()equal()小测试(1)未重写hashCode()equal()(2)重写hashCode()equal()二、重写equals()为什么一定要重写hashCode()? 前言 重写hashCode()equals()相信有不少小伙伴是在学HashMap或HashSet中接触到的,下面这篇文章彻底带你搞懂这两个方法的作用 一、重写hashCode()equal()小测试 (1)未重写hashCode()equal() 首先来看下面这段代码,你们认为h

weixin_51201930的博客 1970

JavaBean,为什么重写hashCode()方法equals()方法及如何重写

Object类中equals()方法的源码/*因为Student这个JavaBean没有重写关于属性值相等的equals()方法,所以默认比较的是地址值,从而输出结果为false*/那么为什么重写equals方法的时候需要重写hashCode方法呢?主要是Object.hashCode的通用约定:在java应用程序运行时,无论何时多次调用同一个对象时的hsahCode()方法,这个对象的hashCode()方法的返回值必须是相同的一个int值.

2401_87029424的博客 834

java重写equals()方法hashCode()方法

1.equals()方法hashCode()方法是什么? equals()hashCode()都是是Java中万物之源Object类中的方法equals方法用于比较两个对象是否相同,Object类中equals方法的实现是比较引用地址来判断的对象是否是同一个对象,通过...

测试0901-1 242

为什么重写hashCode()时,必须重写equals()?

1、保证单一原则:equals相同的两个对象的hashcode必须相同。如果重写equals而没有重写hashcode,会出现equals相同hashcode不相同这个现象。2、在无序集合中(如Set),使用hashcode来计算key应存储在hash表的索引,如果重写equals而没有重写hashcode,会出现两个完全相同的对象。因为hashcode不同,计算出的索引不同,那么这些集合就会混乱。

S1ANS的博客 3110

Java 重写 equals()方法时,为什么必须重写 hashcode()

为什么重写 equals()方法时,不能再用默认的 hashcode 实现,而必须重写 hashcode() ? hashcode()的默认实现: Object 对象中的默认实现返回的是对象的内存地址 如果每个对象都是唯一的,则默认实现工作正常 如果重写 equals(),则表示隐含地说具有不同地址的对象可以彼此相同,在这种情况下,必须覆盖 hashcode() 想想String类. ...

huangdingsheng的博客 441

为什么重写hashCode()方法equals()方法以及如何进行重写

一、前言 本篇文章主要探讨的问题有三个: 1、首先我们为什么需要重写hashCode()方法equals()方法? 2、在什么情况下需要重写hashCode()方法equals()方法? 3、如何重写这两个方法? 二、为什么需要重写hashCode()方法equals()方法 首先,为什么重写equals()方法。我们在定义类时,我们经常会希望两个不同对象的某些属性值相同时就认为他们相同,所以我们要重写equals()方法,按照原则,我们重写equals()方法,也要重写hashCode()方法

qq_43842093的博客 1751

hashCode() 有什么用?为什么要有 hashCode为什么重写 equals() 时必须重写 hashCode() 方法

的作用是获取哈希码( 整数),也称为散列码。这个哈希码的作用是确定该对象在哈希表中的索引位置。 定义在 JDK 的 类中,这就意味着 Java 中的任何类都包含有 函数。另外需要注意的是: 的 方法是本地方法,也就是用 C 语言或 C++ 实现的。 散列表存储的是键值对(key-value),它的特点是:能根据“键”快速的检索出对应的“值”。这其中就利用到了散列码!(可以快速找到所需要的对象) 我们以“ 如何检查重复”为例子来说明为什么要有

lrh35的博客 717

重写equals方法hashcode_说说 hashcode() equals() 的作用、区别、联系?

hashCode()方法equal()方法的作用其实一样,在Java里都是用来对比两个对象是否相等一致,那么equal()既然已经能实现对比的功能了,为什么还要hashCode()呢?因为重写的equal()里一般比较的比较全面比较复杂,这样效率就比较低,而利用hashCode()进行对比,则只要生成一个hash值进行比较就可以了,效率很高,那么hashCode()既然效率这么高为什么还要equ...

weixin_39770416的博客 381

[小技巧]重写equals()时,顺手重写hashCode()

本文通过Java代码示例说明了ArrayList.remove()方法失效的原因及解决方案。当尝试删除Student对象时,由于未重写equals()方法,导致new Student(1,0)被视为不同对象而删除失败。正确的做法是同时重写equals()hashCode()方法,确保逻辑相等的对象具有相同的哈希值。文章强调这不仅是编码规范要求,更是为了避免在哈希集合中出现逻辑错误。最后给出了简单的hashCode()实现模板,并建议养成同时重写这两个方法的习惯,以预防未来可能出现的bug。

weixin_74080197的博客 538
上一篇: 定义一个方法将字符串翻转
下一篇: 流的知识框架
jing_bufferfly
博客等级 码龄11年 5粉丝 19原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值