Java中,数据类型分为基本数据类型和引用数据类型。equals()方法和==都是比较两个数据是否相等的,不同的是==用于比较两个基本数据类型,而equals()方法比较两个引用数据类型。==没有什么说的,它比较的是变量里面存放的值,直接拿两个变量进行比较就完了,而equals()方法本来也是直接比较两个变量里面存放的值(地址值),但是如果我们重写了equals()方法就比较的是两个对象了。下面给大家说一下equals()方法的用法吧!
首先,equals()方法是Object类中的方法,在源代码中如下图所示。
我们可以看到在Object类中equals()方法 的底层还是使用的==进行判断,所以如果我们在比较两个引用数据类型时要先在对应的类中重写这个equals()方法,否则和直接使用==没什么区别。
下面我们分别举3个案例来对equals()方法进行深入的剖析。
1、创建一个时间类并实例化两个时间对象,比较两个时间对象是否相等。试编写代码。
我们先尝试不重写equals()方法,代码如下。
public class Test {
public static void main(String[] args) {
Time t1 = new Time(2022,8,21);
Time t2 = new Time(2022,8,21);
System.out.println(t1.equals(t2));
}
}
class Time {
int hour;
int minutes;
int second;
public Time() {
}
public Time(int hour, int minutes, int second) {
this.hour = hour;
this.minutes = minutes;
this.second = second;
}
}
这是执行的结果,本来我们创建的2个时间对象t1和t2都是2022年8月21日,我们的初衷就是这两个时间相等,但是比较的结果却是false,这是因为没有重写equals()方法时,其底层还是使用的==进行比较,而==比较的是变量里面存放的值,t1和t2都是指向对象的引用,里面的存放的是两个时间对象的地址,由于是两个不同的对象,所以这两个地址不一样,那么比较的结果当然就是false咯。可见比较两个引用数据时,必须要重写equals()方法。下面是重写equals()方法之后的效果。
public class Test {
public static void main(String[] args) {
Time t1 = new Time(2022,8,21);
Time t2 = new Time(2022,8,21);
System.out.println(t1.equals(t2));
}
}
class Time {
int hour;
int minutes;
int second;
public Time() {
}
public Time(int hour, int minutes, int second) {
this.hour = hour;
this.minutes = minutes;
this.second = second;
}
//重写equals()方法
public boolean equals(Object obj) {
//传进来的obj引用为空或者obj引用不是一个Time对象,那肯定不相等,直接返回false
if(obj == null || !(obj instanceof Time)) return false;
//如果当前对象和obj的地址都一样的话,那也不用比较了,肯定是相等的,直接返回true
if(this == obj) return true;
Time t = (Time) obj; //这里obj是Object类型的对象,首先要向下转型为Time类型的对象
//如果两个对象的小时、分钟和秒都相等的话,表示两个对象相等,返回true
if(this.hour == t.hour && this.minutes == t.minutes && this.second ==t.second) return true;
return false; //否则返回false
}
}
2、创建一个学生类,类中有年龄和姓名,如果年龄和姓名都相等就表示该学生是同一个学生。请创建两个学生对象并判断他们是否是同一个学生。试编写代码。
public class Test {
public static void main(String[] args) {
Student s1 = new Student(20,"zhangsan");
Student s2 = new Student(20,"zhangsan");
System.out.println(s1.equals(s2));
}
}
class Student {
int age;
String name;
public Student() {
}
public Student(int age, String name) {
this.age = age;
this.name = name;
}
//重写equals()方法
public boolean equals(Object obj) {
//传进来的obj引用为空或者obj引用不是一个Student对象,那肯定不相等,直接返回false
if(obj == null || !(obj instanceof Student)) return false;
//如果当前对象和obj的地址都一样的话,那也不用比较了,肯定是相等的,直接返回true
if(this == obj) return true;
Student s = (Student) obj; //这里obj是Object类型的对象,首先要向下转型为Student类型的对象
//如果两个对象的年龄和姓名都相等的话,表示两个对象相等,返回true
if(this.age == s.age && this.name.equals(s.name)) return true;
return false; //否则返回false
}
}
这里需要注意的就是在Student类中重写equals()方法的时候比较两个对象的姓名是否相等时也用的equasl()方法,而姓名我给的String类型,按理说我不是应该也要在String类里面重写equals()方法吗?可是我并没有给String类重写equals()方法,实际上是因为sun公司在制定Java语言的时候就已经帮我们写好了,不需要我们去写了。
3、编写一个人类和一个住址类,每个人都有自己的家庭住址,假如2个人的名字和住址一样,我们就说这两个人是同一个人。而住址类有所在城市、街道和邮编,只有这三个都相等的时候才能说住址相同。试编写代码。
public class Test {
public static void main(String[] args) {
Address a1 = new Address("西安","科技路","1111");
Address a2 = new Address("西安","科技路","1111");
People p1 = new People("zhangsan",a1);
People p2 = new People("zhangsan",a2);
System.out.println(p1.equals(p2));
}
}
class People {
String name;
Address address;
public People() {
}
public People(String name, Address address) {
this.name = name;
this.address = address;
}
public boolean equals(Object obj) {
if(obj == null || !(obj instanceof People)) return false;
if(this == obj) return true;
People p = (People) obj;
if(this.name.equals(p.name) && this.address.equals(p.address)) return true;
return false;
}
}
class Address {
String city; //城市
String street; //街道
String zipcode; //邮编
public Address() {
}
public Address(String city, String street, String zipcode) {
this.city = city;
this.street = street;
this.zipcode = zipcode;
}
public boolean equals(Object obj) {
if(obj == null || !(obj instanceof Address)) return false;
if(this == obj) return true;
Address a = (Address) obj;
if(this.city.equals(a.city) && this.street.equals(a.street) && this.zipcode.equals(a.zipcode)) return true;
return false;
}
}
这个题目需要注意,在比较两个人的家庭住址时,由于住址类也是我们自己写的引用数据类型,所以不但People类要重写equals()方法,住址类也要重写equals()方法,总的来说就是今后我们在写代码的过程中,最好每个自定义类都要重写equals()方法。