比較字串

為了比較 Strings 的相等性,你應該使用 String 物件的 equalsequalsIgnoreCase 方法。

例如,以下程式碼段將確定 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。例如,如果你用英語比較兩個單詞 TakiTAKI,它們是相等的; 然而,在土耳其語中他們是不同的(土耳其語,小寫的 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)

如果 foonull,則 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_ORDERComparator<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 來允許使用 == 比較字串。但是,這樣做有很多問題; 看到陷阱 - 實際的字串,以便你可以使用==是一個壞主意的細節。在大多數情況下不建議使用。