Java中比較兩個字符串是否相等的問題

  Java中比較兩個字符串是否相等的問題

  Java中,關於比較兩個字符串是否相等的問題,經常會出現。下面將分析使用 ==(注意:Java中 = 是賦值運算符,== 是比較是否相等) 和 equals()方法 來比較兩個字符串相等的區別:

  簡單一句話,==比較的是兩個字符串的地址是否爲相等(同一個地址),equals()方法比較的是兩個字符串對象的內容是否相同(當然,若兩個字符串引用同一個地址,使用equals()比較也返回true)。

  字符串比較之所以看起來複雜,是因爲值類型和引用類型兩種數據類型的區別:值類型,例如 int 類型,當定義並初始化兩個 int 類型的變量,int i = 1;int j = i,這兩個變量 i , j 存放的的就是1這個值,使用 if(i == j)判斷時,自然返回 i 和 j 是相等的 。引用類型,例如字符串類型, 當定義並初始化兩個字符串類型的變量,String s = "abc"; String s2 = s; 實際上是隻創建了一個String類型的對象,該對象的值爲abc,而 s 和 s2 都引用這一個對象。(關於值類型和引用類型的內容稍後會更新)

 基礎篇:

  下面將舉出兩個例子,分析兩種情況下的字符串比較問題:

  例1. 使用new關鍵字聲明兩個String類型的變量

           

        
1 String s1 = new String("abc"); 2     String s2 = new String("abc"); 3 4      //分別使用.equals()和==進行比較 5     if(s1.equals(s2)) 6     { 7       System.out.println("可以使用 equals 來比較"); 8     }else 9     { 10       System.out.println("不可以使用 equals 來比較"); 11      } 12      if(s1 == s2) 13      { 14        System.out.println("可以使用== 來比較"); 15      }else   16     { 17        System.out.println("不可以使用== 來比較"); 18     }

  運行程序發現,用equals比較返回true,用 == 比較返回false。原因如下:

  因爲 == 比較的是兩個字符串對象的地址是否相同(是否爲同一個地址),當使用new關鍵字創建一個對象的時候,該對象單獨佔據一塊存儲空間,存放llg這個字符串的值。所以s1 s2兩個字符串雖然值相同,但是存儲的地址不是一個地址,例如兩個人都叫l“李四”但是他們的住址不在一個地方。當使用==來比較的時候,比較的是兩個字符串的地址是否是同一個,所以返回false。但是使用equals()方法比較這兩個字符串,將會比較兩個字符串的值是否相同,所以返回true。

  例2. 正常情況下的字符串聲明並定義。   

      //聲明並初始化兩個賦值一樣的字符串

      String s1 = "abc";
      String s2 = "abc";

      //使用.equals()方法比較兩個字符串是否相等
      if(s1.equals(s2))
      {
         System.out.println("可以使用 equals  來比較");
      }else
      {
         System.out.println("不可以使用 equals  來比較");
      }

      //使用 == 比較兩個字符串是否相等
        if(s1 == s2)
        {
         System.out.println("可以使用 == 來比較");
        }else
        {
          System.out.println("不可以使用 == 來比較");
        }

  程序經過運行,發現兩個方式都返回true。那麼這是爲什麼呢?原因如下:

  一般我們認爲,棧中存放基本類型的變量和對象的引用變量,而new出來的對象和數組存放在堆中。然而除此之外還有一塊區域叫做常量池。像我們通常想String s1 = "abc"; 這樣申明的字符串對象,其值就是存儲在常量池中。當我們創建String s1 = "abc"這樣一個對象之後,"abc"就存儲到了常量池中,當我們創建引用String s2 = "abc" 的時候,Java底層會優先在常量池中查找是否存在"abc",如果存在則讓s2指向這個值,不會重新創建。所以使用 == 比較時,因爲地址相同,所以比較的結果是true。

  那麼問題回來了,既然是有常量池,是不是字符串如果不是new出來的(一般也不會這麼new,聲明字符串變量一般像例2這麼寫),那麼這些字符串都是從常量池引用同一個對象,所以用 == 比較就行了?答案是可以。

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