Java中比較相等,有兩種方法,各有不同,使用的地方也就不一樣,這裏我們分別探究一下:
==用來比較基本數據類型或者具有繼承關係的引用類型,如果是基本類型,我們只關心值是不是一致(與數據類型無關),而如果是引用類型,我們比較的是兩個對象是否指向的是同一個地址,看下面的實例:
class Per{
public String name;
public Per() {
}
public Per(String name) {
super();
this.name = name;
}
}
public class Test07 {
public static void main(String[] args) {
//基本數據類型
int i1 = 10;
int i2 = 11;
float f = 10f;
System.out.println(i1==i2);//false
System.out.println(i1==f);//true
//引用數據類型
Per p1 = new Per();
Per p2 = new Per();
Per p3 = p1;
System.out.println(p1==p2);//false
System.out.println(p1==p3);//true
//包裝類
Integer in1 = 10;
Integer in2 = 10;
System.out.println(in1==in2);//true
Integer in3 = new Integer(10);
Integer in4 = new Integer(10);
System.out.println(in3==in4);//false
Double d = 10.0;
System.out.println(in1==i1);//true
// System.out.println(in1==d);//錯的,沒有直接的繼承關係
}
}
由上面的代碼可以證明上面的概念,這裏面要注意一點,當包裝類與之對應的基本類型相比值一樣的時候,返回的是true,如果是包裝類與包裝類比較,那麼如果使用new 賦值的是false,而使用=直接賦值的是true,這是因爲我們直接用=賦值時會自動拆箱成基本類型比較,這樣比較的值一致即可。
其實我們在一般的編程中使用的比較希望是值比較,不希望是地址比較,那麼我們就可以使用equals()方法比較,但是equals()方法比較的時候,默認也不是進行值比較而是使用地址比較,這個我們要追溯到equals()在Object裏的定義,因爲equals()方法和toString()方法一樣,如果不重寫將使用Object裏面定義的,那麼先看一下Object裏的equals方法的源碼:
public boolean equals(Object obj) {
return (this == obj);
}
可以看出,Object中的equals方法也是調用了==來比較的,這樣也是地址比較,但是我們來看看下面的代碼:
String s1 = new String("a");
String s2 = new String("a");
System.out.println(s1.equals(s2));//true
兩個引用類型的比較值也是true,這樣就達到了值比較的目的,那麼我們看看toString的equals源碼:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String) anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
很明顯是重寫過了,那麼在自己定義的類裏面也可以重寫equals()方法來實現我們需要的比較。
最後粘出對於String的equals方法的源碼理解:
public boolean equals(Object anObject) {
//如果兩個類的引用地址一樣,說明是一個對象,肯定相等
if (this == anObject) {
return true;
}
//instanceof判斷是否有繼承關係,沒有繼承關係之間返回假
if (anObject instanceof String) {
String anotherString = (String) anObject;
//字符串在Java中是以字符數組存放的,value就是當前的字符數組
int n = value.length;
//兩個字符數組(即字符串)的單獨不一致,直接返回假
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
//判斷對應位置的每一個值是不是一樣
while (n-- != 0) {
//如果有一個不一樣,返回假
if (v1[i] != v2[i])
return false;
i++;
}
//走到這裏已經判斷完了所有的不可能的情況,返回的是真的了
return true;
}
}
return false;
}
/*
* 這種思想就是一步一步的排除不一樣的情況,從大的方面判斷到小的方法,一步步的排除,
* 一旦有爲假的情況,直接返回假,退出,這樣最大程度的減少判斷
* 當然也不是一定非要排除錯的情況,剛開始就判斷了是不是真,最直接的目的是提高效率
* 儘量在少的判斷下得出結論
*/