equals()和==

Equals()和==
一、大致介绍
连等号是判断是否属于同一个对象(即指向的内存是否一样)。而equals()则分2种情况:①若对象是immutable,则是从观察等价性上进行判断。 ②若对象是mutable,则从行为等价性进行判断,即2个是否为同一个对象。
即对于对象是mutable的,equals()和连等号的作用是一样的。
原方法提供的equals()方法是实现行为等价性,故对于immutable对象而言,要重写equals()方法,因为immutable只需实现观察等价性。
二、具体例子
2.1基本类型例子
观察以下代码和运行结果,我们可以发现:两者不是指向同一个内存,故连等号判断为false。且两者都是指字符串”aaa”,故连等号判断为true
在这里插入图片描述
在这里插入图片描述

改成这样子的话,两个判断就应该都为true
在这里插入图片描述
在这里插入图片描述

2.2自己设计的mutable ADT
由于此ADT中有方法能改变其中的属性,故我们应该通过行为等价性来判断是否为同一个对象,即此时用原方法的equals()即可,这里比较简单故不作详述。

2.3自己设计的immutable ADT
对于自己设计的immutable的ADT而言,需要重写equals()方法和HashCode()方法。因为Object实现的是行为等价性,此时由于是immutable我们只需实现观察等价性。可以看到我们设计的Person类是immutable
在这里插入图片描述
在这里插入图片描述

判断结果是false,原因是我们没有重写equals()和HashCode()方法,导致ming和ming1不是同一个对象所以判断出错。此时我们应该重写equals()方法和HashCode()方法(重写HashCode()是为了Set<>里可以找到),接下来举例子。

在这里插入图片描述
在Eclipse的Source处有一个一键生成equals()和hashCode()的功能,此时为了步步演示,我们先只生成equals()方法。
在这里插入图片描述
此时自动重写了equals()方法,然后我们再运行程序。
在这里插入图片描述
发现结果为true,即此时我们需要判断对象相等,仅需让他们的域都相等即可。
我们先下一个定理:一旦你重写了equals(),你也就必须重写hashCode(),这两个的重写应该是成对出现的。接下来我们来解释为什么。
此时我们改变main函数,按原来的想法,我现在已经实现了ming.equals(ming1)=true了,那此时我map.put(ming,1),此时我去寻找map.get(ming1)应该得找到ming的value值1.

在这里插入图片描述
在这里插入图片描述

运行后发现竟然找到ming的value值。我们思考其原因,对map的get操作本质上是通过每个对象的hashCode来进行寻值的,我map.put一个对象后,就会通过该对象的地址来为其分配hashCode,接下来我们map.get寻值的时候就是通过一个个匹配hashCode来找到目标对象的value值。而我们此时实现的equals()是通过比较所有的属性相等后,则判断两个对象相等,但是main函数里的ming和ming1的地址是不相等的,所以会无法寻值。因此,我们需要重写hashCode,实现我们所认为的对象相等。

这是自动生成的hashCode(),可以看到其实就是对属性进行唯一的代数运算。
在这里插入图片描述

接着我们运行,发现结果正确,可以找到ming对应的value值1了。
在这里插入图片描述

三、对于Integer的一个小扩展
Integer不是基本数据类型。此时我指明是new一个对象,故下面判断应为false。
在这里插入图片描述
在这里插入图片描述

此时我们重改一下写的方式,此时按理说应该也得a!=b,因为是Integer而不是int,但是结果却是相等的。
在这里插入图片描述
在这里插入图片描述

此时把数据改大一点
在这里插入图片描述
在这里插入图片描述

发现结果竟然变为false了。究其原因,Java在设计的时候,为了防止我们在处理一些常用数据(-128~127)时,一直重复的new Integer对象,故在此范围内,main函数的a和b是指向同一个内存地址的,相当于直接去系统里取数。而超出这个范围,就得一直new Integer对象。且这个特性只对Integer满足,我们随便改为Double,结果为false。
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值