Java基础_语法(equals和==以及重写equals和hashcode)

目录

1:==和equals

1.1:==和equals的区别

1.2:hashcode方法(C语言方法,返回地址指针值)

1.3:equals方法

2:重写equals和hashcode

2.1:String类的equals和hashcode

2.2:自定义类型测试(没有重写equals和hashcode)

2.3:自定义类型测试(重写equals,不重写hashcode)

2.4:自定义类型测试(重写equals,重写hashcode)


1:==和equals

 

1.1:==和equals的区别

==:比较的是内存中的地址是否相同

equals:该方法根据不同的类的实现方式,有不同的含义,重写父类Object方法的话就按照自己的定义来,没有重写的话就是跟==相同。

 

我们知道在 Java 语言中object是所有类的父类,所有的类默认继承object类,这个继承关系是在java 编译器编译的时候实现的继承。

public  class  MyClass

在编译器编译的过程会变成

public class  MyClass  extends Object

在父类object中有两个方法分别是hashCode()和equals()方法

 

1.2:hashcode方法(C语言方法,返回地址指针值)

 public native int hashCode();

native关键字是本地的意思,就是说hashcode是一个本地方法,由于java不直接操作内存地址指针,表明hashcode是一个C语言实现的方法,意思是返回内存上存储位置的指针值。

 

1.3:equals方法

通过代码我们可以看到,父类object中的equals实际上就是==,实现类如果没有重写equals方法,那么equals方法就是==

public boolean equals(Object obj) {

        return (this == obj);

    }

 

2:重写equals和hashcode

2.1:String类的equals和hashcode

自定义测试类

我们结合String在内存中堆栈上的存储位置,来理解为什么会出现如下结果:

 

我们常用的String类,equals和hashcode都已经重写了。我们分析源码作为参考

首先查看hashcode方法如下:重写之后返回一个整形数值。保证不同的字符串,返回不同的值

接着我们查看equals方法:

 

由此我们可以看到,String重写了equals方法,变成了比较了字符串的值。但是String还重写了hashcode方法,他为什么需要重写呢?我们暂时也没有用到,带着这些疑问我们接着往下分析。

2.2:自定义类型测试(没有重写equals和hashcode)

在自定义测试类测试类之前我们,假设一个情况,若两个用户的账户和姓名相等我们就认为这两个用于是一样的。


我们在user中有id和name属性

然后我们测试:

 


2.3:自定义类型测试(重写equals,不重写hashcode)

这个时候由于我们想要当账户密码想等的时候,我们的equals要判断他们想等,我们继续需要重写equals方法,

重写equals如下,参考String的equals思路

测试结果如下:

看到这里,在没有重写hashcode的情况下,我们也能得到两个对象想等的结果。心里会想没问题了。

但是接着往下看 ,我们把这两个对象放到set里边,由于set是不能重复的,结果会如何呢?

我们看到set的长度是2,为什么把这相同的对象都放到set里边的呢?这个时候就需要我们重写hashcode方法。

 

2.4:自定义类型测试(重写equals,重写hashcode)

为什么需要重写hashcode方法呢?

因为在jdk中(Obejct的hashcode方法注释中给到了三条建议),要求我们重写,在前边的案例中,我们重写完equals方法,单单比较对象还没有什么意外发生,一但我们将对象放到容器里边,容器底层的数据结构是哈希表的,默认会初始化一个长度是16的数组,按照哈希code在数组上找对应的数组下标是否有数据,然后比对数据是否重复。如果我们没有重写hashcode那么这两个相同的对象,会对应到不同的数组位置,导致数据放重复,例如set,hashmap等

 

我们能随意重写hashcode方法吗?显然是不能的,重写hashcode要满足三个规范

1:同一个new出来的对象,hashcode必须相同。

2:如果两个对象equals相同,hashcode一定相同。(不相同的话会导致set重复,如上边的例子)

3:如果两个对象equals不相同,那么hashcode不一定相同,但是强烈建议hashcode也不能相同,这样能提升哈希表性能。(如果hashcode相同,这种情况会导致哈希表恶化,因为哈希表根据hashcode在数组上找到元素位置,假如10个对象的hashcode相同,会导致他们放到同一个位置,但是他们的equals不相同,会导致哈希表桶结构过长,极端情况退化为链表,影响性能)

我们重写equals和hashcode方法测试


添加完成hashcode方法之后,测试结果如下:

由此这些这步骤我们知道了重写equals方法如果要使用到容器,底层是哈希表的容器,比如set,hashmap等需要重写hashcode方法,并且按照重写方法的三个条件来设计hashcode函数,不然会造成重复数据或者严重的hashcode冲突 。

  • 19
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值