Java比较字符串

示例

为了比较字符串是否相等,应使用String对象equals或equalsIgnoreCase方法。

例如,以下代码段将确定的两个实例String在所有字符上是否相等:

String firstString = "Test123";
String secondString = "Test" + 123;

if (firstString.equals(secondString)) {
   // 这两个字符串具有相同的内容。
}

现场演示

本示例将比较它们,而与它们的情况无关:

String firstString = "Test123";
String secondString = "TEST123";

if (firstString.equalsIgnoreCase(secondString)) {
    // 两个字符串都是相等的,忽略了各个字符的大小写。
}

现场演示

请注意, equalsIgnoreCase不允许您指定Locale。例如,如果您比较两个单词,"Taki"而"TAKI"在英语中它们是相等的;但是,在土耳其语中,它们是不同的(在土耳其语中,小写字母I是ı)。对于这种情况,解决方案是将两个字符串都使用转换为小写(或大写),Locale然后与进行比较equals。

String firstString = "Taki";
String secondString = "TAKI";

System.out.println(firstString.equalsIgnoreCase(secondString)); //打印真实

Locale locale = Locale.forLanguageTag("tr-TR");

System.out.println(firstString.toLowerCase(locale).equals(
                   secondString.toLowerCase(locale))); //打印错误

现场演示


不要使用==运算符比较字符串

除非您可以保证所有字符串都已被内联(请参见下文),否则不应使用==或!=运算符来比较字符串。这些运算符实际上测试引用,并且由于多个String对象可以表示同一个String,因此很容易给出错误的答案。

而是使用方法,该方法将根据字符串对象的值进行比较。有关详细说明,请参阅陷阱:使用==比较字符串。String.equals(Object)


在switch语句中比较字符串

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"); //代码在这里
        break;
    case "B":
        System.out.println("B");
        break;
    default:
        break;
}

现场演示

比较具有常数值的字串

将aString与常量值进行比较时,可以将常量值放在的左侧,equals以确保NullPointerException如果另一个String为,则不会得到a null。

"baz".equals(foo)

虽然foo.equals("baz")将抛出NullPointerException,如果foo是null,  将评估到。"baz".equals(foo)false

Java SE 7

更具可读性的替代方法是使用,它对两个参数进行空检查。Objects.equals()Objects.equals(foo, "baz")

注意:通常最好避免NullPointerExceptions,还是让它们发生然后解决根本原因,这是有争议的。请在这里和这里查看。当然,将避免策略称为“最佳实践”是没有道理的。)

字符串顺序

的String类实现Comparable<String>与所述String.compareTo方法(在此示例中的开始所描述的)。这使得String对象的自然排序区分大小写。的String类提供一个Comparator<String>称为恒定CASE_INSENSITIVE_ORDER适于不区分大小写的排序。

与内联字符串比较

Java语言规范(JLS 3.10.6)声明以下内容:

“此外,一个字符串总是指类的同一实例String这是因为字符串文字-或,更一般地,字符串是常量表达式的值-被拘留以便共享独特实例,使用方法String.intern”。

这意味着它是安全的引用比较两个字符串文字使用==。此外,对于String使用该方法生产的对象的引用也是如此。String.intern()

例如:

String strObj = new String("Hello!");
String str = "Hello!";

// 两个字符串引用指向两个相等的字符串
if (strObj.equals(str)) {
    System.out.println("The strings are equal");
}

// 这两个字符串引用没有指向同一对象
if (strObj != str) {
    System.out.println("The strings are not the same object");
}

// 如果我们内联等于给定文字的字符串,则结果为
// 与文字具有相同引用的字符串。
String internedStr = strObj.intern();

if (internedStr == str) {
    System.out.println("The interned string and the literal are the same object");
}

在幕后,内部机制维护一个哈希表,该表包含所有仍可到达的内部字符串。调用intern()时String,该方法在哈希表中查找对象:

  • 如果找到该字符串,则该值作为实习字符串返回。

  • 否则,将字符串的副本添加到哈希表中,并将该字符串作为实习字符串返回。

可以使用interning允许使用比较字符串==。但是,这样做存在很大的问题。请参阅陷阱-中断字符串,以便可以使用==获取详细信息,这是个坏主意。在大多数情况下不建议这样做。