1. ==
== 是運算子,用來判斷兩個值是否相等,==可以使用在基本資料型別變數和參考資料型別變數中
1.1 基本資料型別
Java基本資料型別共有八種,可以分為三類
- 字符型別char
- 布爾型別boolean
- 數值型別byte、short、int、long、float、double
這里有個例外,boolean不參與數值運算
int a1 = 10;
int a2 = 10;
System.out.println(a1==a2); //true
float a3 = 5.0f;
float a4 = 5.0f;
System.out.println(a3==a4); //true
……
上面給出幾組示例,相同資料型別可以相互比較不用多說了,那么不同資料型別呢?
int a1 = 10;
byte b1 = 10;
System.out.println(a1==b1); //true
char c1 = 'A';
int c2 = 65;
System.out.println(c1 == c2); //true
int a1 = 10;
double d1 = 10.0d;
System.out.println(a1==d1); //true
int a1 = 10;
char e1 = 10;
System.out.println(a1==e1); //true
可以看到,在基本資料型別的范圍內,不同資料型別也是可以直接比較的
如果比較的是基本資料型別,就是判斷兩個保存的資料是否相同(不一定型別相同)
1.2 參考資料型別
這里先寫一個Student類,用于參考
public class Student {
public String name;
public int age;
public Student(){}
public Student(String name, int age){
this.name = name;
this.age = age;
}
}
實體化兩個Student物件,判斷是否相等
Student student1 = new Student("Tom", 18);
Student student2 = new Student("Tom", 18);
System.out.println(student1==student2); //false
注意,這里出現了示例中的第一個false,可以看到,即使賦的值是相同的,但使用==判斷的結果為false,這是因為兩個物件在記憶體中不指向同一地址,
如果比較的是參考型別,就是比較兩個變數是否代表同一物件物體,也就是是否指向同一地址
1.3 小結
==是運算子
可以使用在基本資料型別變數和參考資料型別變數中
如果比較的是基本資料型別,就是判斷兩個保存的資料是否相同,不一定型別相同
如果比較的是參考型別,就是比較兩個變數是否代表同一物件物體,也就是是否指向同一地址
2. equals
equals()是方法,只能用于參考資料型別
還是使用上面介紹到的Student物件,如果使用equals比較,那么?
Student student1 = new Student("Tom", 18);
Student student2 = new Student("Tom", 18);
System.out.println(student1.equals(student2)); //false
答案還是false,我們可以看一下在此處使用的equals的原始碼

使用的正是Object中的equals()方法(繼承),而Object中的equals()方法也是使用的==進行的比較
Object類中equals()和==的作用相同
誒,部分同學可能想說了,這個equals()和我們平時用的不太一樣啊,平時用的equals()好像是用來比較數值的,這里我們拿String類來舉例,
String str1 = new String("cun");
String str2 = new String("cun");
System.out.println(str1==str2); //false
System.out.println(str1.equals(str2)); //true
使用==比較,不出意外是false,而這里使用equals(),得到的結果是true,我們看一下這里的equals()原始碼(Java8版本)

可以看到,String類中的equals()重寫了Object類中的equals(),這里側重于具體的數值比較(我們日常使用中也是更希望比較具體的數值),分析一下原始碼,這里先使用==進行比較,然后判斷是否為String的一個示例,判斷長度是否相等,最后挨個判斷字符是否相等,
原始碼的大部分程式都比較好理解,有些人比較迷惑這里的強制轉換(如下圖),既然前一句判斷了是否為String類的實體,后一句為什么還要強轉?這是因為,在Java中,代碼從撰寫到執行要經歷兩個程序——編譯和執行,在執行時,程式判斷了實參是否為String類的實體物件,之后不再需要強轉;但是在編譯中,即使經歷了instanceof判斷,編譯器還是會始終把傳進來的引數當作Object型別,而Object型別是沒有value屬性的,會直接報錯,所以在這里如果不強轉,編譯都通不過,更不用說執行了,

類似的,我們可以寫出Student類中重寫的equals()方法,
不過現在因為類使用的非常多,一方面是因為每個類都添加比較繁瑣,另一方面我們可能寫的可能不夠健壯,這里提供兩種方式自動提供equals()的重寫
- IDEA編譯器的快捷鍵“alt + insert”,選擇如下圖的選項

選擇需要添加到equals()的屬性

可以看到自動生成的程式
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age &&
Objects.equals(name, student.name);
}
- 匯入lombok包,加入Data注解
@Data
public class Student {
public String name;
public int age;
public Student(){}
public Student(String name, int age){
this.name = name;
this.age = age;
}
}
可以看到重寫了Object類中的equals()方法

3. 總結
/**
* ==是運算子,equals是方法
* 1. ==
* 可以使用在基本資料型別變數和參考資料型別變數中
* 如果比較的是基本資料型別,就是判斷兩個保存的資料是否相同,不一定型別相同
* 如果比較的是參考型別,就是比較兩個變數是否代表同一物件物體,也就是是否指向同一地址
*
* 2. equals
* 只能適用于參考資料型別
* Object類中equals()和==的作用相同
* 像String、Data、File、包裝類等中的equals都是重寫了Object類中的equals()方法,比較的是物體內容是否相同
*/
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/353648.html
標籤:java
下一篇:將SQL查詢轉換為等效的LINQ
