In order to compare Strings for equality, you should use the String object's equals
or equalsIgnoreCase
methods.
For example, the following snippet will determine if the two instances of String
are equal on all characters:
String firstString = "Test123";
String secondString = "Test" + 123;
if (firstString.equals(secondString)) {
// Both Strings have the same content.
}
This example will compare them, independent of their case:
String firstString = "Test123";
String secondString = "TEST123";
if (firstString.equalsIgnoreCase(secondString)) {
// Both Strings are equal, ignoring the case of the individual characters.
}
Note that equalsIgnoreCase
does not let you specify a Locale
. For instance, if you compare the two words "Taki"
and "TAKI"
in English they are equal; however, in Turkish they are different (in Turkish, the lowercase I
is ı
). For cases like this, converting both strings to lowercase (or uppercase) with Locale
and then comparing with equals
is the solution.
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
Unless you can guarantee that all strings have been interned (see below), you should not use the ==
or !=
operators to compare Strings. These operators actually test references, and since multiple String
objects can represent the same String, this is liable to give the wrong answer.
Instead, use the String.equals(Object)
method, which will compare the String objects based on their values. For a detailed explanation, please refer to Pitfall: using == to compare strings.
As of Java 1.7, it is possible to compare a String variable to literals in a switch
statement. Make sure that the String is not null, otherwise it will always throw a NullPointerException
. Values are compared using String.equals
, i.e. case sensitive.
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;
}
When comparing a String
to a constant value, you can put the constant value on the left side of equals
to ensure that you won't get a NullPointerException
if the other String is null
.
"baz".equals(foo)
While foo.equals("baz")
will throw a NullPointerException
if foo
is null
, "baz".equals(foo)
will evaluate to false
.
A more readable alternative is to use Objects.equals()
, which does a null check on both parameters: Objects.equals(foo, "baz")
.
(Note: It is debatable as to whether it is better to avoid NullPointerExceptions
in general, or let them happen and then fix the root cause; see here and here. Certainly, calling the avoidance strategy "best practice" is not justifiable.)
The String
class implements Comparable<String>
with the String.compareTo
method (as described at the start of this example). This makes the natural ordering of String
objects case-sensitive order. The String
class provide a Comparator<String>
constant called CASE_INSENSITIVE_ORDER
suitable for case-insensitive sorting.
The Java Language Specification (JLS 3.10.6) states the following:
"Moreover, a string literal always refers to the same instance of class
String
. This is because string literals - or, more generally, strings that are the values of constant expressions - are interned so as to share unique instances, using the methodString.intern
."
This means it is safe to compare references to two string literals using ==
. Moreover, the same is true for references to String
objects that have been produced using the String.intern()
method.
For example:
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");
}
Behind the scenes, the interning mechanism maintains a hash table that contains all interned strings that are still reachable. When you call intern()
on a String
, the method looks up the object in the hash table:
It is possible to use interning to allow strings to be compared using ==
. However, there are significant problems with doing this;
see Pitfall - Interning strings so that you can use == is a bad idea for details. It is not recommended in most cases.