Java中判断对象是否相等的equals方法使用教程资料.docx
- 文档编号:5444351
- 上传时间:2022-12-16
- 格式:DOCX
- 页数:19
- 大小:23.97KB
Java中判断对象是否相等的equals方法使用教程资料.docx
《Java中判断对象是否相等的equals方法使用教程资料.docx》由会员分享,可在线阅读,更多相关《Java中判断对象是否相等的equals方法使用教程资料.docx(19页珍藏版)》请在冰豆网上搜索。
Java中判断对象是否相等的equals方法使用教程资料
与==运算符响应,equals()方法也是Java中对对象进行比较的一大方式,要特别注意二者的不同点,这个我们在下文中即将讲到,接下来我们就来看一下Java中判断对象是否相等的equals()
方法使用教程
Object类中的equals方法用于检测一个对象是否等于另一个对象。
在Object类中,这个方
法判断两个对象是否具有相同的引用,如果两个对象具有相同的引用,它们一定是相等的。
从这点上看,将其作为默认操作也是合乎情理的。
然而,对于多数类类说,这种判断并没有
什么意义,例如,采用这种方式比较两个PrintStream是否相等就完全没有意义。
然而,经
常需要检测两个对象状态的相等性,如果两个对象的状态相等,就认为这两个对象是相等的。
所以一般在自定义类中都要重写equals比较。
F面给出编写一个完美equals()方法的建议:
(1)显式参数命名为otherObject,稍后需要将转换成一个叫other的变量
(2)检测this与otherObject是否引用同一个对象:
1
if(this==otherObject)returntrue;
这条语句只是一个优化。
实际上,这是一种经常采用的形式。
因为计算这个等式要比一个一
个地比较类中的域所付出的代价小的多。
(3)检测otherObject是否为null,如果为null,返回false。
这项检测是很必要的。
1
if(otherObject==null)returnfalse;
(4)比较this和otherObject是否属于同一个类,如果equals的语义在每个子类中有所改变,就使用getClass()检测,它将自己作为目标类
1if(getClass()!
=otherObject.getClass())returnfalse;
如果所有的子类都拥有同一的语义,就使用instanceof检测
1if(!
(otherObjectinstanceofClassName))returnfalse;
(5)将otherObject转换为相应类型的变量:
1ClassNameother=(ClassName)otherObject;
(6)现在开始对所有需要比较的域进行比较。
使用==比较基本类型域,使用equals比较对
象域。
如果所有域都匹配,就返回true,否则返回false;
1returnfield1==other.field1&&field2.equals(other.field2)
如果在子类中重新定义equals,就要在其中包含调用super.equals(other)。
如果检测失败,就
不可能相等。
如果超类中的域相等,就比较子类中的实例域。
对于数组类型的域,可以使用静态的Arrays.equals方法检测相应的元素是否相等。
来看几个字符串比较例子:
1
Stringa="abc";
2
Stringb="abc";
3
Stringc=newString("abc");
4
Stringd=newString("abc");
5
System.out.println(a==b);//true因为JAVA中字符串常量是共享的,只有一个拷贝
6
〔System.out.println(a--c);//falsea和c属于2个不冋的对象1
7System.out.println(a.equals(c));//true由于String对象的equals方法比较的是对象中的值,
8所以返回true。
(和Object的equals方法不同)
9System.out.println(c==d);//falsec和d虽然对象内的值相同,但属于2个不同的对象,所
以不相等
System.out.println(c.equals(d));//true
简单的说,当比较字符串常量时,等于和equals返回的结果一样,当想比较字符串对象的值时用equals。
看一个equals的使用例子:
1
packagechapterO5.EqualsTest;
2
importjava.util.*;
3
publicclassEqualsTest{
4
publicstaticvoidmain(String[]args){
5
Employeealice1=newEmployee("AliceAdams",75000,1987,12,15);
6
Employeealice2=alice1;//referencethesameobject
7
Employeealice3=newEmployee("AliceAdams",75000,1987,12,15);
8
Employeebob=newEmployee("BobBrandson",50000,1989,10,1);
9
System.out.println("alice1==alice2:
"+(alice1==alice2));
10
System.out.println("alice1==alice3:
"+(alice1==alice3));
11
System.out.println("alice1.equals(alice3):
"+(alice1.equals(alice3)));
12
System.out.println("alice1.equals(bob):
"+(alice1.equals(bob)));
13
System.out.println(bob.toString());
14
}
15
}
16
classEmployee{
17
publicEmployee(Stringn,doubles,intyear,intmonth,intday){
18
name=n;
19
salary=s;
20
GregorianCalendarcalendar=newGregorianCalendar(year,month,day);
21
hireDay=calendar.getTime();
22
}
23
publicStringgetName(){
24
returnname;
25
}
26
publicdoublegetSalary(){
27
returnsalary;
28
}
29
publicDategetHireDay(){
30
returnhireDay;
31
}
32
publicvoidraiseSalary(doublebyPercent){
33
doubleraise=salary*byPercent/100;
34
salary+=raise;
35
}
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
publicbooleanequals(ObjectotherObject){
//aquicktesttoseeiftheobjectsareidenticalif(this==otherObject)returntrue;
//mustreturnfalseiftheexplicitparameterisnull
if(otherObject==null)returnfalse;
//iftheclasseddon'tmatch,theycan'tbeequal
if(getClass()!
=otherObject.getClass())returnfalse;
//nowweknowotherObjectisawww.hunanwang.netyeeEmployeeother=(Employee)otherObject;
//testwhetherthefieldshavaidenticalvaluesreturnname.equals(other.name)&&salary==other.salary
&&hireDay.equals(other.hireDay);
}
@Override
publicinthashCode(){
return7*name.hashCode()+11*newDouble(salary).hashCode()+13*hireDay.hashCode();
}
@Override
publicStringtoString(){
returngetClass().getName()+"[name="+name+",salary="+salary
+",hireDay="+hireDay+"]";
}
privateStringname;
privatedoublesalary;
privateDatehireDay;
}
classManagerextendsEmployee{
publicManager(Stringn,doubles,intyear,intmonth,intday){
super(n,s,year,month,day);
bouns=0;
}
@Override
publicdoublegetSalary(){
doublebaseSalary=super.getSalary();
returnbaseSalary+bouns;
}
publicvoidsetBouns(doubleb){
bouns=b;
}
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
@Override
publicbooleanequals(ObjectotherObject){
if(!
super.equals(otherObject))
returnfalse;
Managerother=(Manager)otherObject;
//superequalscheckedthatthisandotherbelongtothesameclassreturnbouns==other.bouns;
}
@Override
publicinthashCode(){
returnsuper.hashCode()+17*newDouble(bouns).hashCode();
}
@Override
publicStringtoString(){
returnsuper.toString()+"[bouns="+bouns+"]";
}
privatedoublebouns;
}
深入
下面根据"类是否覆盖equals。
方法”,将它分为2类。
(1)若某个类没有覆盖equals。
方法,当它的通过equals。
比较两个对象时,实际上是比较两个对象是不是同一个对象。
这时,等价于通过"==”去比较这两个对象。
⑵我们可以覆盖类的equals。
方法,来让equals。
通过其它方式比较两个对象是否相等。
通常的做法是:
若两个对象的内容相等,则equals。
方法返回true;否则,返回fasle。
下面,举例对上面的2种情况进行说明。
1."没有覆盖equals()方法”的情况
代码如下(EqualsTestl.java):
1
2
3
4
importjava.util.*;
5
importjava.Iang.Comparable;
6
/**
7
*@descequals()的测试程序。
8
*/
9
publicclassEqualsTest1{
10
publicain(String[]args){
11
//新建2个相同内容的Person对象,
12
//再用equals比较它们是否相等
13
Personp1=newPerson("eee",100);
14
Personp2=newPerson("eee",100);
15
System.out.printf("%s\n",p1.equals(p2));
16
}
17
/**
18
*@descPerson类。
19
*/
20
privatestaticclassPerson{
21
intage;
22
Stringname;
23
publicPerson(Stringname,intage){
24
this.name=name;
25
this.age=age;
26
}
27
publicStringtoString(){
28
returnname+"-"+age;
29
}
30
}
31
}
32
33
34
运行结果:
复制代码代码如下
false
结果分析
我们通过p1.equals(p2)来"比较pl和p2是否相等时”。
实际上,调用的Object.java的equals。
方法,即调用的(p仁=p2)。
它是比较“pl和p2是否是同一个对象”。
而由pl和p2的定义可知,它们虽然内容相同;但它们是两个不同的对象!
因此,返回结
false。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
2."覆盖equals。
方法”的情况
我们修改上面的EqualsTest1.java:
覆盖equals。
方法。
代码如下(EqualsTest2.java):
importjava.util.*;
importjava.Iang.Comparable;
/**
*@descequals()的测试程序。
*/
publicclassEqualsTest2{
publicstaticvoidmain(String[]args){
//新建2个相同内容的Person对象,
//再用equals比较它们是否相等
Personp1=newPerson("eee",100);
Personp2=newPerson("eee",100);
System.out.printf("%s\n",p1.equals(p2));}
/**
*@descPerson类。
*/
privatestaticclassPerson{
intage;
Stringname;
publicPerson(Stringname,intage){this.name=name;
this.age=age;
}
publicStringtoString(){
returnname+"-"+age;
}
/**
*@desc覆盖equals方法
*/
@Override
publicbooleanequals(Objectobj){if(obj==null){returnfalse;
}
false
//如果是同一个对象返回true,反之返回
if(this==obj){
returntrue;
}
〃判断是否类型相同
if(this.getClass()!
=obj.getClass()){returnfalse;
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
}
Personperson=(Person)obj;
returnname.equals(person.name)&&age==person.age;}
}
}
运行结果:
复制代码代码如下
true
结果分析:
我们在EqualsTest2.java中重写了Person的equals()函数:
当两个Person对象的name和age都相等,则返回true。
因此,运行结果返回true。
讲到这里,顺便说一下java对equals()的要求。
有以下几点:
对称性:
如果x.equals(y)返回是"true",那么y.equals(x)也应该返回是"true"。
反射性:
x.equals(x)必须返回是"true"。
类推性:
如果x.equals(y)返回是"true",而且y.equals(z)返回是"true",那么z.equals(x)也应该返回是"true"。
一致性:
如果x.equals(y)返回是"true",只要x和y内容一直不变,不管你重复x.equals(y)
多少次,返回都是"true"。
非空性,x.equals(null),永远返回是"false";x.equals(和x不同类型的对象)永远返回是"false"。
现在,再回顾一下equals()的作用:
判断两个对象是否相等。
当我们重写equals()的时候,可
千万不好将它的作用给改变了!
equals()与==的区别是什么?
==:
它的作用是判断两个对象的地址是不是相等。
即,判断两个对象是不是同一个对象。
equals():
它的作用也是判断两个对象是否相等。
但它一般有两种使用情况(前面第1部分已
详细介绍过):
情况1,类没有覆盖equals()方法。
则通过equals()比较该类的两个对象时,等价于通过“==”
比较这两个对象。
情况2,类覆盖了equals()方法。
一般,我们都覆盖equals()方法来两个对象的内容相等;若
它们的内容相等,则返回true(即,认为这两个对象相等)。
下面,通过示例比较它们的区别。
代码如下:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
importjava.util.*;
importjava.Iang.Comparable;
/**
*@descequals。
的测试程序。
*/
publicclassEqualsTest3{
publicstaticvoidmain(String[]args){
//新建2个相同内容的Person对象,
//再用equals比较它们是否相等
Personp1=newPerson("eee",100);
Personp2=newPerson("eee",100);
System.out.printf("p1.equals(p2):
%s\n",p1.equals(p2));
System.out.printf("p1==p2:
%s\n",p1==p2);
}
/**
*@descPerson类。
*/
privatestaticclassPerson{
intage;
Stringname;
publicPerson(Stringname,intage){this.name=name;
this.age=age;
}
publicStringtoString(){
returnname+"-"+age;
}
/**
*@desc覆盖equals方法
*/
@Override
publicbooleanequals(Objectobj){
if(obj==null){
returnfalse;
}
//如果是同一个对象返回true,反之返回false
if(this==obj){
returntrue;
}
〃判断是否类型相同
if(this.getClass()!
=obj.getClass()){returnfalse;
}
Personperson=(Person)obj;
45
46
47
48
49
50
51
52
53
54
55
56
57
returnname.equals(person.name)&&age==person.age;}
}
}
运行结果:
1p1.equals(p2):
true
2p1==p2:
false
结果分析:
在EqualsTest3.java中:
(1)p1.equals(p2)
这是判断p1和p2的内容是否相等。
因为Person覆盖equals()方法,而这个equals()是用来
判断p1和p2的内容是否相等,恰恰p1和p2的内容又相等;因此,返回true。
⑵p1==p2
这是判断p1和p2是否是同一个对象。
由于它们是各自新建的两个Person对象;因此,返
回false。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Java 判断 对象 是否 相等 equals 方法 使用 教程 资料