Java String類的比較運算


面試題:(多選)以下返回true的有()

A. "beijing" == "beijing"

B. "beijing".equals(new String("beijing"))

C. "beijing" == new String("beijing")

D. String a = "beijing";

    String b = "beijing";

    a == b

E. String a = new String("beijing")

    String b = new String("beijing");

    a == b

答案是 A,B,D

private void testSring() {
    if ("beijing" == "beijing") {
     System.out.println(
"this is equal1"); } if ("beijing".equals(new String("beijing"))) { System.out.println("this is equal2"); } if ("beijing" == new String("beijing")) { System.out.println("this is equal3"); } String a = "beijing"; String b = "beijing"; if (a == b) { System.out.println("this is equal4"); } String m = new String("beijing"); String n = new String("beijing"); if (m == n) { System.out.println("this is equal5"); } }

執行結果為:
this is equal1
this is equal2
this is equal4

以下分析轉載自:http://blog.sina.com.cn/s/blog_6fd8a5870100qimb.html

Java中的String類是一種復合數據類型,比較String 類的是否相等也有2種辦法。"=="和equals()兩種。

String 是一個系統定義的類----不是基本數據類型,有關字符串處理的方法非常多,有時候兩個“一樣”的字符串做相等的比較運算時會得到true的結果,可是有的時候得到的結果卻是false,這是為什么呢?

要徹底的弄清這兩個字符串的相等比較,還得從系統的內存分配着手。

1 棧和堆的區別

棧和堆都是java 在ram中的數據存儲區,java自動管理棧和堆,程序員不能直接設置棧和堆。

1.1棧

棧的存取速度僅次於位於cpu中的寄存器,比堆的存取速度快,棧中數據項的插入和刪除,只能在棧頂的一端完成,棧的操作特性后進先出。棧中存放一些基本類型的變量和對象句柄,棧中的數據可以共享,缺點::存放在棧中的數據大小與生存期必須是確定的,缺乏靈活性,比如有如下例子:

int a = 3; int b = 3;

編譯器先處理int a = 3,首先它會在棧中創建一個整形變量為a的引用,然后在棧中查找有沒有值為3的存儲單元,如果沒有就開辟一個存放值為3的存儲單元,然后將a指向這個值為3的地址,接着處理int b = 3,在創建完變量b的引用后,由於棧中已經有了值為3的地址,這樣就出現了a和b同時指向3的情況。

假如再有a= 4,在編譯器內部它會重新搜索棧中是否有值為4的存儲單元,如果沒有,重新開辟地吃存放4的存儲單元;如果有則直接將a指向這個地址。因此a值的改變不會影響到b的值。

1.2堆

堆是一個運行時數據區,類的對象從中分配空間,通過如new等指令建立。堆的優點是可以動態的分配內存大小。生存期也不必事先告訴編譯器,java的垃圾收集器會自動回收不再使用的數據。但缺點是,由於要在運行時動態非配內存,存取速度比較慢。

 

2 字符串 ==”的比較

String是一個特殊的包裝類數據。當測試兩個包裝類的引用是否指向同一個對象時,用“==”。

String 類的對象有兩種形式創建:

形式1:String  str = “abc”;

形式 2:String str = new String(“abc”) ;

 

2.1 兩者都為第一種形式創建的對象的比較

String  str1 = “abc”;

String  str2 = “abc”;

用語句String str1 = “abc”;創建對象java內部將此語句轉換為以下幾個步驟:

(1) 先定義一個名為str1 的對String類的對象引用變量。

(2) 在棧中查找有沒有存放值為“abc”的存儲單元,接着創建一個新的Sting類的對象0,並將對象0指向這個存儲單元,而且在棧中記下這個引用的對象0.如果已經有了值為“abc”的地址則查找對象0,並返回對象0的地址。

(3) 將str1指向對象0的地址。Str1指向存在棧中的數據的引用。

String  str2 =”abc”;在棧中創建了一個對象引用str2.因為棧中已經有一個值為“abc”的對象0,因此jvm創建了兩個引用str1和str2,但只創建了一個對象,而且這兩個引用都指向了這個對象,所以這里str1 == str2.

 

2.2 同為第二種形式創建的兩個對象的比較

如:String str1 = new String(“abc”);

String str2 = new String(“abc”);

System.out.println(str1 ==str2);

系統在棧內存中分別創建了兩個對象引用變量str1和str2,同時在堆內存中創建了兩個對象。兩個引用變量分別表示兩個不同的對象,如圖所示,

java中關於String類的比較運算

無論堆內存中是否有相同的數據存在,也不會像棧中的數據共享。因此str1 != str2.

 

2.3兩種不同形式創建對象的比較

String  str1 = new String(“abc”);

String str2 = “abc”;

System.out.println(str1 == str2); //false

 

Str1和str2是棧中創建的兩個引用,str1 指向了堆中的一個對象,而str2則指向了棧中的一個對象,即兩個引用分別指向不同的兩個對象,所以str1 != str2.

 

3 字符串值的比較

如果要比較兩個字符串的值就用equals()方法。如:str1.equals(str2)只要str1和str2的字面值相等結果就為true.

結論

(1) String  str = “abc”;指向String類的引用被創建了。至於這個引用是否指向了一個新的對象,根據上下文來考慮。

(2) String str = new String(“abc”);在棧中創建了一個對象的引用srt,str指向在堆中創建的新對象。該對象值為“abc”的String類。

(3) 當比較包裝類里面的數值是否相等時,用equals方法,當測試兩個包裝類的引用是否指向一個對象的時候,用“==”。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM