2012-02-23 41 views
5

如果兩個相同的String實際上不完全相同,那麼爲什麼我可以使用字符串作爲HashMap中的鍵而不使用相同的String對象?爲什麼我可以使用字符串作爲HashMap中的鍵?

String s1 = "Test"; 
String s2 = "Test"; 

System.out.println(s1 == s2); // should be false 
System.out.println(s1.equals(s2)); // should be true 

HashMap<String, String> map = new HashMap(); 
map.put(s1, "foo"); 
System.out.println(map.get(s2)); // should be "foo"--but why? 

是否HashMapString對象的一些特殊行爲?如果沒有,爲什麼可以使用兩個「不同的」字符串來放置並從散列中獲取值?

+6

請注意,由於字符串內聯,'s1 == s2'將爲'true'。 – 2012-02-23 23:37:21

+0

那麼爲什麼使用'.equals()'比較'String'的標準做法? – 2012-02-23 23:40:13

+1

@Ted Hopp s1 == s2將由於*常量池*而成立。 – EJP 2012-02-23 23:42:50

回答

14

HashMap通過調用equals()hashCode()來比較對象。
String將重寫這些方法以按值進行比較。

4

兩個字符串是相同不等於實際

但他們。它們在equals()方法下是相同的,這是在Map接口中爲相等性測試指定的技術。

System.out.println(s1 == s2); // should be false 

但它不是假的!由於編譯器的常量池,兩者都引用相同的字符串。

2

HashMap在內部比較密鑰時,它使用equals()方法,而不是==。因此,反對平等是罰款的關鍵比賽,是不是如果equals()被覆蓋

5

在一般情況下,你可以使用String對象,因爲HashMap的使用equals()而不是==來測試所需的參考平等(如在java.lang.String的情況。)關鍵的平等。

1

System.out.println(s1 == s2); //應該是假的

它不應該。 Java編譯器可以優化並將兩個字符串指向同一位置。

更新

public class Test { 

    public static void main(String... args) { 
     String s1 = "abc"; 
     String s2 = "abc"; 

     System.out.println(s1 == s2); 
    } 

} 

輸出

javac Test.java 
java Test 
> true 
+0

錯,錯,錯。你可以用簡單的代碼輕鬆地證明它。 – duffymo 2012-02-23 23:46:46

+3

不,這沒有錯。它被稱爲「實習」。 – 2012-02-23 23:54:24

+2

「可以優化」我認爲你的意思是「必須優化」,假設Java編譯器符合規範。 http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#3.10.5 – yshavit 2012-02-24 00:07:07

-2

我們真的應該回到基本的。

計算機科學的基礎:

==比較存儲器地址(參考)

.equals比較存儲在存儲器地址

java的基本值。在整個jvm中只有一個字符串對象的副本

+3

幾乎你的答案中的每一行都是微妙或明顯的錯誤 – SLaks 2012-02-26 17:15:30

+0

這些不是'計算機科學基礎'。他們是* Java *基礎。 Java引用不一定是內存地址。如果使用'new String(...)'構造,則可以有多個字符串的副本。 – EJP 2017-07-15 19:38:14

相關問題