You should not use == (equality operator) to compare these strings because they compare the reference of the string, i.e. whether they are the same object or not. On the other hand, equals() method compares whether the value of the strings is equal, and not the object itself.
The right way of comparing String in Java is to either use equals(), equalsIgnoreCase(), or compareTo() method. You should use equals() method to check if two String contains exactly same characters in same order. It returns true if two String are equal or false if unequal.
In order to compare two strings, we can use String's strcmp() function. The strcmp() function is a C library function used to compare two strings in a lexicographical manner. The function returns 0 if both the strings are equal or the same. The input string has to be a char array of C-style string.
==
tests for reference equality (whether they are the same object).
.equals()
tests for value equality (whether they are logically "equal").
Objects.equals() checks for null
before calling .equals()
so you don't have to (available as of JDK7, also available in Guava).
Consequently, if you want to test whether two strings have the same value you will probably want to use Objects.equals()
.
// These two have the same value
new String("test").equals("test") // --> true
// ... but they are not the same object
new String("test") == "test" // --> false
// ... neither are these
new String("test") == new String("test") // --> false
// ... but these are because literals are interned by
// the compiler and thus refer to the same object
"test" == "test" // --> true
// ... string literals are concatenated by the compiler
// and the results are interned.
"test" == "te" + "st" // --> true
// ... but you should really just call Objects.equals()
Objects.equals("test", new String("test")) // --> true
Objects.equals(null, "test") // --> false
Objects.equals(null, null) // --> true
You almost always want to use Objects.equals()
. In the rare situation where you know you're dealing with interned strings, you can use ==
.
From JLS 3.10.5. String Literals:
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 (§15.28) - are "interned" so as to share unique instances, using the methodString.intern
.
Similar examples can also be found in JLS 3.10.5-1.
String.equalsIgnoreCase() value equality that ignores case. Beware, however, that this method can have unexpected results in various locale-related cases, see this question.
String.contentEquals() compares the content of the String
with the content of any CharSequence
(available since Java 1.5). Saves you from having to turn your StringBuffer, etc into a String before doing the equality comparison, but leaves the null checking to you.
==
tests object references, .equals()
tests the string values.
Sometimes it looks as if ==
compares values, because Java does some behind-the-scenes stuff to make sure identical in-line strings are actually the same object.
For example:
String fooString1 = new String("foo");
String fooString2 = new String("foo");
// Evaluates to false
fooString1 == fooString2;
// Evaluates to true
fooString1.equals(fooString2);
// Evaluates to true, because Java uses the same object
"bar" == "bar";
But beware of nulls!
==
handles null
strings fine, but calling .equals()
from a null string will cause an exception:
String nullString1 = null;
String nullString2 = null;
// Evaluates to true
System.out.print(nullString1 == nullString2);
// Throws a NullPointerException
System.out.print(nullString1.equals(nullString2));
So if you know that fooString1
may be null, tell the reader that by writing
System.out.print(fooString1 != null && fooString1.equals("bar"));
The following are shorter, but it’s less obvious that it checks for null:
System.out.print("bar".equals(fooString1)); // "bar" is never null
System.out.print(Objects.equals(fooString1, "bar")); // Java 7 required
==
compares Object references.
.equals()
compares String values.
Sometimes ==
gives illusions of comparing String values, as in following cases:
String a="Test";
String b="Test";
if(a==b) ===> true
This is because when you create any String literal, the JVM first searches for that literal in the String pool, and if it finds a match, that same reference will be given to the new String. Because of this, we get:
(a==b) ===> true
String Pool
b -----------------> "test" <-----------------a
However, ==
fails in the following case:
String a="test";
String b=new String("test");
if (a==b) ===> false
In this case for new String("test")
the statement new String will be created on the heap, and that reference will be given to b
, so b
will be given a reference on the heap, not in String pool.
Now a
is pointing to a String in the String pool while b
is pointing to a String on the heap. Because of that we get:
if(a==b) ===> false.
String Pool
"test" <-------------------- a
Heap
"test" <-------------------- b
While .equals()
always compares a value of String so it gives true in both cases:
String a="Test";
String b="Test";
if(a.equals(b)) ===> true
String a="test";
String b=new String("test");
if(a.equals(b)) ===> true
So using .equals()
is always better.
The ==
operator checks to see if the two strings are exactly the same object.
The .equals()
method will check if the two strings have the same value.
Strings in Java are immutable. That means whenever you try to change/modify the string you get a new instance. You cannot change the original string. This has been done so that these string instances can be cached. A typical program contains a lot of string references and caching these instances can decrease the memory footprint and increase the performance of the program.
When using == operator for string comparison you are not comparing the contents of the string, but are actually comparing the memory address. If they are both equal it will return true and false otherwise. Whereas equals in string compares the string contents.
So the question is if all the strings are cached in the system, how come ==
returns false whereas equals return true? Well, this is possible. If you make a new string like String str = new String("Testing")
you end up creating a new string in the cache even if the cache already contains a string having the same content. In short "MyString" == new String("MyString")
will always return false.
Java also talks about the function intern() that can be used on a string to make it part of the cache so "MyString" == new String("MyString").intern()
will return true.
Note: == operator is much faster than equals just because you are comparing two memory addresses, but you need to be sure that the code isn't creating new String instances in the code. Otherwise you will encounter bugs.
String a = new String("foo");
String b = new String("foo");
System.out.println(a == b); // prints false
System.out.println(a.equals(b)); // prints true
Make sure you understand why. It's because the ==
comparison only compares references; the equals()
method does a character-by-character comparison of the contents.
When you call new for a
and b
, each one gets a new reference that points to the "foo"
in the string table. The references are different, but the content is the same.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With