比較字串
為了比較 Strings 的相等性,你應該使用 String 物件的 equals
或 equalsIgnoreCase
方法。
例如,以下程式碼段將確定 String
的兩個例項是否在所有字元上相等:
String firstString = "Test123";
String secondString = "Test" + 123;
if (firstString.equals(secondString)) {
// Both Strings have the same content.
}
這個例子將比較它們,與它們的情況無關:
String firstString = "Test123";
String secondString = "TEST123";
if (firstString.equalsIgnoreCase(secondString)) {
// Both Strings are equal, ignoring the case of the individual characters.
}
請注意, equalsIgnoreCase
不允許你指定 Locale
。例如,如果你用英語比較兩個單詞 Taki
和 TAKI
,它們是相等的; 然而,在土耳其語中他們是不同的(土耳其語,小寫的 I
是ı
)。對於這樣的情況,使用 Locale
將兩個字串轉換為小寫(或大寫),然後與 equals
進行比較是解決方案。
String firstString = "Taki";
String secondString = "TAKI";
System.out.println(firstString.equalsIgnoreCase(secondString)); //prints true
Locale locale = Locale.forLanguageTag("tr-TR");
System.out.println(firstString.toLowerCase(locale).equals(
secondString.toLowerCase(locale))); //prints false
不要使用==運算子來比較字串
除非你能保證所有字串都已被實現(見下文),否則你不應該使用 ==
或 !=
運算子來比較字串。這些運算子實際上測試引用,並且因為多個 String
物件可以表示相同的 String,所以這可能給出錯誤的答案。
相反,使用 String.equals(Object)
方法,它將根據字串的值比較 String 物件。有關詳細說明,請參閱陷阱:使用==來比較字串 。
在 switch 語句中比較字串
Version => Java SE 7
從 Java 1.7 開始,可以將一個 String 變數與 switch
語句中的文字進行比較。確保 String 不為 null,否則它將始終丟擲 NullPointerException
。使用 String.equals
比較值,即區分大小寫。
String stringToSwitch = "A";
switch (stringToSwitch) {
case "a":
System.out.println("a");
break;
case "A":
System.out.println("A"); //the code goes here
break;
case "B":
System.out.println("B");
break;
default:
break;
}
將字串與常量值進行比較
將 String
與常量值進行比較時,可以將常數值放在 equals
的左側,以確保如果另一個字串是 null
,則不會得到 NullPointerException
。
"baz".equals(foo)
如果 foo
是 null
,則 foo.equals("baz")
將投擲 NullPointerException
,而 "baz".equals(foo)
將評估為 false
。
Version => Java SE 7
更可讀的替代方法是使用 Objects.equals()
,它對兩個引數進行空檢查:Objects.equals(foo, "baz")
。
( 注意: 關於一般是否更好地避免 NullPointerExceptions
,或者讓它們發生然後解決根本原因是否更好是有爭議的;請看這裡和這裡 。當然,將撤銷策略稱為最佳實踐是不合理的。)
字串排序
String
類使用 String.compareTo
方法實現 Comparable<String>
(如本例開頭所述)。這使得 String
物件的自然排序區分大小寫。String
類提供了一個名為 CASE_INSENSITIVE_ORDER
的 Comparator<String>
常量,適用於不區分大小寫的排序。
與實習字串比較
Java 語言規範( JLS 3.10.6 )宣告如下:
“此外,字串文字總是引用類
String
的相同例項。這是因為字串文字 - 或者更常見的是作為常量表示式值的字串 - *被實現,*以便使用方法String.intern
共享唯一例項。 “
這意味著使用 ==
比較對兩個字串文字的引用是安全的。此外,對於使用 String.intern()
方法生成的 String
物件的引用也是如此。
例如:
String strObj = new String("Hello!");
String str = "Hello!";
// The two string references point two strings that are equal
if (strObj.equals(str)) {
System.out.println("The strings are equal");
}
// The two string references do not point to the same object
if (strObj != str) {
System.out.println("The strings are not the same object");
}
// If we intern a string that is equal to a given literal, the result is
// a string that has the same reference as the literal.
String internedStr = strObj.intern();
if (internedStr == str) {
System.out.println("The interned string and the literal are the same object");
}
在幕後,實習機制維護一個雜湊表,其中包含仍可訪問的所有內部字串。當你在 String
上呼叫 intern()
時,該方法會在雜湊表中查詢物件:
- 如果找到該字串,則該值將作為實習字串返回。
- 否則,將字串的副本新增到雜湊表中,並將該字串作為實習字串返回。
可以使用 interning 來允許使用 ==
比較字串。但是,這樣做有很多問題; 看到陷阱 - 實際的字串,以便你可以使用==是一個壞主意的細節。在大多數情況下不建議使用。