为了比较字符串是否相等,应使用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)
从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
更具可读性的替代方法是使用,它对两个参数进行空检查。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允许使用比较字符串==。但是,这样做存在很大的问题。请参阅陷阱-中断字符串,以便可以使用==获取详细信息,这是个坏主意。在大多数情况下不建议这样做。