携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第22天,点击查看活动详情
哈喽,大家好!我是Why,一名在读学生,目前刚刚开始进入自己的编程学习生涯。虽然学习起步较晚,但我坚信做了才有0或1的可能。学了一段时间以后也是选择在掘金上分享自己的日常笔记,也希望能够在众多道友的大家庭中打成一片。 本文主要讲解equals方法详解,如果大家读后觉得有用的话,还请大家多多支持博主:欢迎 ❤️点赞👍、收藏⭐、留言💬 ✨✨✨个人主页:JinHuan
equals方法
/*
关于Object类中的equals方法
1、equals方法的源代码
public boolean equals(Object obj) {
return (this == obj);
}
以上这个方法是Object类的默认实现。
2、SUN公司设计equals方法的目的是什么?
以后编程的过程当中,都要通过equals方法来判断两个对象是否相等。
equals方法是判断两个对象是否相等的。
3、我们需要研究一下Object类给的这个默认的equals方法够不够用!!!!
在Object类中的equals方法当中,默认采用的是“==”判断两个java对象
是否相等。而“==”判断的是两个java对象的内存地址,我们应该判断
两个java对象的内容是否相等。所以老祖宗的equals方法不够用,
需要子类重写equals。
4、判断两个java对象是否相等,不能使用“==”,因为“==”比较的是两个
对象的内存地址。
5、建议所有子类重写equals方法(注意使用instance of)
*/
栗子
public class Test02{
public static void main(String[] args){
// 判断两个基本数据类型的数据是否相等直接使用“==”就行。
int a = 100;
int b = 100;
// 这个“==”是判断a中保存的100和b中保存的100是否相等。
System.out.println(a == b); //true(相等) false(不相等)
// 判断两个java对象是否相等,我们怎么办?能直接使用“==”吗?
// 创建一个日期对象是:2008年8月8日。
MyTime t1 = new MyTime(2008, 8, 8); //MyTime t1 = 0x1234;
// 创建了一个新的日期对象,但表示的日期也是:2008年8月8日。
MyTime t2 = new MyTime(2008, 8, 8); //MyTime t2 = 0x3698;
//测试以下,比较两个对象是否相等,能不能使用“==”???
// 这里的“==”判断的是:t1中保存的对象内存地址和t2中保存的对象内存地址是否相等。
System.out.println(t1 == t2); // false
// 重写Object equals方法之前(比较的是对象内存地址)
/*
boolean flag = t1.equals(t2);
System.out.println(flag); //false
*/
// 重写Object equals方法之后(比较的是内容。)
boolean flag = t1.equals(t2);
System.out.println(flag); //true
// 再创建一个新的日期
MyTime t3 = new MyTime(2008, 8, 9);
// 两个日期不相等,就是false。
System.out.println(t1.equals(t3)); // false
// 我们这个程序有bug吗?可以运行,但是效率怎么样?低(怎么改造。)
MyTime t4 = null;
System.out.println(t1.equals(t4)); //false
}
}
class MyTime { //extends Object{
int year;
int month;
int day;
public MyTime(){
}
public MyTime(int year, int month, int day){
this.year = year;
this.month = month;
this.day = day;
}
// 默认的equals方法
/*
public boolean equals(Object obj) {
return (this == obj);
}
*/
/*
// 重写Object类的equals方法
// 怎么重写?复制粘贴。相同的返回值类型、相同的方法名、相同的形式参数列表。
// equals到底应该怎么重写?你自己定,你认为两个对象什么相等的时候表示相等,你就怎么重写。
public boolean equals(Object obj) {
// 当年相同,月相同,并且日也相同的时候,表示两个日期相同。两个对象相等。
// 获取第一个日期的年月日
int year1 = this.year;
int month1 = this.month;
int day1 = this.day;
// 获取第二个日期的年月日
//int year2 = obj.year;
//int month2 = obj.month;
//int day2 = obj.day;
if(obj instanceof MyTime){
MyTime t = (MyTime)obj;
int year2 = t.year;
int month2 = t.month;
int day2 = t.day;
if(year1 == year2 && month1 == month2 && day1 == day2){
return true;
}
}
// 程序能够执行到此处表示日期不相等。
return false;
}
*/
/*
// 改良equals方法
public boolean equals(Object obj) {
// 如果obj是空,直接返回false
if(obj == null){
return false;
}
// 如果obj不是一个MyTime,没必要比较了 ,直接返回false
if(!(obj instanceof MyTime)){
return false;
}
// 如果this和obj保存的内存地址相同,没必要比较了,直接返回true。
// 内存地址相同的时候指向的堆内存的对象肯定是同一个。
if(this == obj){
return true;
}
// 程序能够执行到此处说明什么?
// 说明obj不是null,obj是MyTime类型。
MyTime t = (MyTime)obj;
if(this.year == t.year && this.month == t.month && this.day == t.day){
return true;
}
// 程序能到这里返回false
return false;
}
*/
//再次改良。
/*
public boolean equals(Object obj) {
// 如果obj是空,直接返回false
if(obj == null){
return false;
}
// 如果obj不是一个MyTime,没必要比较了 ,直接返回false
if(!(obj instanceof MyTime)){
return false;
}
// 如果this和obj保存的内存地址相同,没必要比较了,直接返回true。
// 内存地址相同的时候指向的堆内存的对象肯定是同一个。
if(this == obj){
return true;
}
// 程序能够执行到此处说明什么?
// 说明obj不是null,obj是MyTime类型。
MyTime t = (MyTime)obj;
return this.year == t.year && this.month == t.month && this.day == t.day ;
}
*/
public boolean equals(Object obj) {
if(obj == null || !(obj instanceof MyTime)){
return false;
}
if(this == obj){
return true;
}
MyTime t = (MyTime)obj;
return this.year == t.year && this.month == t.month && this.day == t.day ;
}
}
/*
class Person{
private String idCard;
}
*/
String中的Equals?
/*
java语言当中的字符串String有没有重写toString方法,有没有重写equals方法。
总结:
1、String类已经重写了equals方法,比较两个字符串不能使用==,必须使用equals。
equals是通用的。
2、String类已经重写了toString方法。
大结论:
java中什么类型的数据可以使用“==”判断
java中基本数据类型比较是否相等,使用==
java中什么类型的数据需要使用equals判断
java中所有的引用数据类型统一使用equals方法来判断是否相等。
这是规矩。
*/
public class Test03{
public static void main(String[] args){
// 大部分情况下,采用这样的方式创建字符串对象
String s1 = "hello";
String s2 = "abc";
// 实际上String也是一个类。不属于基本数据类型。
// 既然String是一个类,那么一定存在构造方法。
String s3 = new String("Test1");
String s4 = new String("Test1");
// new两次,两个对象内存地址,s3保存的内存地址和s4保存的内存地址不同。
// == 判断的是内存地址。不是内容。
System.out.println(s3 == s4); // false
// 比较两个字符串能不能使用双等号?
// 不能,必须调用equals方法。
// String类已经重写equals方法了。
System.out.println(s3.equals(s4)); // true
// String类有没有重写toString方法呢?
String x = new String("尽欢");
// 如果String没有重写toString()方法,输出结果:java.lang.String@十六进制的地址
// 经过测试:String类已经重写了toString()方法。
System.out.println(x.toString()); //尽欢
System.out.println(x); //尽欢
}
}
String的equals
// String对象比较的时候必须使用equals方法。
public class Test04{
public static void main(String[] args){
/*
Student s1 = new Student(111, "北京大兴亦庄二小");
Student s2 = new Student(111, "北京大兴亦庄二小");
System.out.println(s1 == s2); // false
System.out.println(s1.equals(s2)); // true
*/
Student s1 = new Student(111, new String("北京大兴亦庄二小"));
Student s2 = new Student(111, new String("北京大兴亦庄二小"));
System.out.println(s1 == s2); // false
System.out.println(s1.equals(s2)); // true
}
}
class Student{
// 学号
int no; //基本数据类型,比较时使用:==
// 所在学校
String school; //引用数据类型,比较时使用:equals方法。
public Student(){}
public Student(int no,String school){
this.no = no;
this.school = school;
}
// 重写toString方法
public String toString(){
return "学号" + no + ",所在学校名称" + school;
}
// 重写equals方法
// 需求:当一个学生的学号相等,并且学校相同时,表示同一个学生。
// 思考:这个equals该怎么重写呢?
// equals方法的编写模式都是固定的。架子差不多。
public boolean equals(Object obj){
if(obj == null || !(obj instanceof Student)) return false;
if(this == obj) return true;
Student s = (Student)obj;
return this.no == s.no && this.school.equals(s.school);
//字符串用双等号比较可以吗?
// 不可以
//return this.no == s.no && this.school == s.school;
}
}
equals的实例
// equals方法重写的时候要彻底。
public class Test05{
public static void main(String[] args){
// 多态(自动类型转换。)
Object o1 = new String("hello world!");
Object o2 = new User();
Object o3 = new Address();
User u1 = new User("zhangsan", new Address("北京","大兴区","11111"));
User u2 = new User("zhangsan", new Address("北京","大兴区","11111"));
System.out.println(u1.equals(u2)); // true
User u3 = new User("zhangsan", new Address("北京","朝阳区","11112"));
System.out.println(u1.equals(u3)); // false
}
}
class User{
// 用户名
String name;
// 用户的住址
Address addr;
public User(){
}
public User(String name, Address addr){
this.name = name;
this.addr = addr;
}
// 重写equals方法
// 重写规则:当一个用户的用户名和家庭住址都相同,表示同一个用户。
// 这个equals判断的是User对象和User对象是否相等。
public boolean equals(Object obj){
// 用户名和用户名相同,住址和住址相同的时候,认定是同一个用户。
if(obj == null || !(obj instanceof User)) return false;
if(this == obj) return true;
User u = (User)obj;
if(this.name.equals(u.name) && this.addr.equals(u.addr)){
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;
}
// 注意:这里并没有重写equals方法。
// 这里的equals方法判断的是:Address对象和Address对象是否相等。
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;
}
}