把equals方法掌握的妥妥的
一. equals方法的源代码
public boolean equals(Object obj) {
return (this == obj);
}
- 以上源码是Object类的默认实现
二. 设计equals的目的是什么?
以后在编程过程中,都要通过equals方法来判断两个对象是否相等,
equals方法是判断两个对象是否相等的
三. Object中equals不够用?!
- 在Object类中的equals方法当中,默认采用的是 == 判断两个Java对象是否相等
- 而 == 比较的是两个Java对象的内存地址
- 应该判断两个Java对象的内容是否相等,所以equals方法不够用
- 需要子类重写equals方法
- Object是所有类的父类,不进行重写,使用的是Object中的equals方法
- Object中判断的是内存地址
四. == 比较的是两个对象的内存地址
- 判断两个Java对象是否相等,不能使用==
public class Test1 {
public static void main(String[] args) {
// 判断两个基本数据类型的数据是否相等直接使用 == 就行
int a = 100;
int b = 100;
// 此 == 是判断 a中保持的100 和 b中的100 是否相等
System.out.println(a == b); // true(相等)
// 判断两个Java对象是否相等,怎么办,直接使用 == 吗
// 创建了一个日期对象
MyTest t1 = new MyTest(2020, 6, 26); // t1 = 0x23434
// 创建了一个新的日期对象,表示的日期也是一样的
MyTest t2 = new MyTest(2020, 6, 26); // t2 = 0x87878
// 测试如下,能否比较两个对象是否相等,能不能使用 == ???
// 这里的 == 判断的是:t1中保存的对象内存地址和t2中保存的内存地址是否相等
System.out.println(t1 == t2); // false
// 重写object equals方法之前
boolean b1 = t1.equals(t2);
System.out.println(b1); // false
}
}
class MyTest { // 默认有extend Object
int year;
int month;
int day;
public MyTest() {
}
public MyTest(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
// 其实这里有默认的equals方法
public boolean equals(Object obj) {
return (this == obj);
}
}
五. 重写equals
- String Integer等类已经重写了equals和toString方法
- toString可以省略不写
public class Test1 {
public static void main(String[] args) {
// 创建了一个日期对象
MyTest t1 = new MyTest(2020, 6, 26); // t1 = 0x23434
// 创建了一个新的日期对象,表示的日期也是一样的
MyTest t2 = new MyTest(2020, 6, 26); // t2 = 0x87878
// 重写object equals方法之后
boolean b1 = t1.equals(t2);
System.out.println(b1); // true
// 再创建一个新的日期
MyTest t3 = new MyTest(2008, 7, 21);
// 因为t1和t2的日期不相等
System.out.println(t1.equals(t3)); // false
}
}
class MyTest {
int year;
int month;
int day;
public MyTest() {
}
public MyTest(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
// 手动重写Object中的equals方法
// 需要相同的返回值类型,方法名,形式参数列表
public boolean equals(Object o) {
// 当年,月,日相同时,表示两个日期相同,两个对象相等
// 获取第一个日期的年月日
int year1 = this.year;
int month1 = this.month;
int day1 = this.day;
// 获取第二个日期的年月日 object中找不到年月日,进行向下转型
if (o instanceof MyTest) {
MyTest t = (MyTest)o;
int year2 = t.year;
int month2 = t.month;
int day2 = this.day;
if (year1 == year2 && month1 == month2 && day1 == day2) {
return true;
}
}
// 程序能执行到此处表示日期不相等
return false;
}
}
- 改良equals方法
// 改良equals方法
public boolean equals(Object o) {
// 如果o是空,直接返回false
if (o == null) {
return false;
}
// 如果o不是一个MyTest。则没必要比较
if (o == null) {
return false;
}
// 如果this和o的内存地址一致,也没必要比较,直接返回true
// 内存地址相同时指向堆内存的对象肯定是同一个
if (this == o) {
return true;
}
// 程序执行到此:说明o不是null,是MyTest类型
MyTest t = (MyTest)o;
if (this.year == t.year && this.month == t.month && this.day == t.day) {
return true;
}
// 程序执行完毕
return false;
}
- 再次改良
// 改良equals方法
public boolean equals(Object o) {
// 如果o是空或者类型是MyTest,返回false
if (o == null || !(o instanceof MyTest)) {
return false;
}
// 如果this和o的内存地址一致,也没必要比较,直接返回true
// 内存地址相同时指向堆内存的对象肯定是同一个
if (this == o) {
return true;
}
// 程序执行到此:说明o不是null,是MyTest类型
MyTest t = (MyTest)o;
return this.year == t.year && this.month == t.month && this.day == t.day;
}
六. 判断类型结论
-
基本数据类型的数据使用 == 判断
-
int i1 = 1; int i2 = 1; System.out.println(i1 == i2); // true float f1 = 1; float f2 = 1; System.out.println(f1 == f2); // true
-
-
引用数据类型需要使用equals判断
-
它们都重写了equals方法
-
Integer i1= new Integer(1); Integer i2 = new Integer(1); System.out.println(i1.equals(i2)); // true String s1 = new String("中国"); String s2 = new String("中国"); System.out.println(s1.equals(s2)); // true
-