5.2 ==和equals比較 -【Java入門--瘋狂Java講義】

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;
    }

/*
 *    這種思想就是一步一步的排除不一樣的情況,從大的方面判斷到小的方法,一步步的排除,
 *    一旦有爲假的情況,直接返回假,退出,這樣最大程度的減少判斷
 *    當然也不是一定非要排除錯的情況,剛開始就判斷了是不是真,最直接的目的是提高效率
 *    儘量在少的判斷下得出結論
 */

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章