This question's answers are a collaborative effort: if you see something that can be improved, just edit the answer to improve it! No additional answers can be added here

12

Also its good to know that, if you are overridding .equals () method, make sure you are overridding .hashcode () method, otherwise you will end up with violating equivalence relation b/w equals and hashcode. For more info refer java doc.
–
SurendharNov 6 '13 at 12:44

== will work some of the time, as java has a String pool, where it tries to reuse memory references of commonly used strings. But == compares that objects are equal, not the values... so .equals() is the proper use you want to use.
–
VenomFangsNov 14 '13 at 23:17

Never use == to test whether Strings are the same, unless you enjoy tracking down subtle errors and studying the intricacies of the Java String interning process. "12"=="1"+2 is false (probably)
–
Flight OdysseyDec 23 '13 at 6:04

23 Answers
23

.equals() tests for value equality (whether they are logically "equal").

Consequently, if you want to test whether two strings have the same value you should use .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

You almost always want to use.equals(). In the rare situation where you know you're dealing with interned strings, you can use ==.

Just a note equals()exactly Compares this String to another String, BUT equalsIgnoreCase() Compares this String to another String, ignoring case considerations
–
Yajli MacloFeb 28 '13 at 15:30

13

@SnakeDoc — We can say the opposite. Always use equals() unless you have a good reason. What you call safety is entirely context-dependent. For instance, when comparing passwords to determine whether the user has entered the right password, it is unsafe to ignore case differences.
–
Nicolas BarbulescoAug 22 '13 at 9:06

17

One minor edit, == is not "much cheaper" than .equals, because the first statement in String.equals reads: if (this == anObject) { return true; }.
–
TorqueApr 10 '14 at 10:42

Alas, there is no static method for isNullOrEmpty(), and no custom overloading of operators, which makes this part of Java clunkier than in C# or Python. And since Java doesn't have extension methods, you can't write your own utility to extend java.lang.String. Right? Any thoughts on subclassing String, adding that static utility method, and then always using MyString instead? A static method with two parameters for doing null-safe comparisons would be nice to have in that subclass too.
–
Jon CoombsJun 20 '14 at 1:00

2

Groovy makes this a little easier with the safe navigation operator (groovy.codehaus.org/…), ?.. That would convert nullString1?.equals(nullString2); into an entirely null statement. However, it doesn't help if you have validString?.equals(nullString); -- that still throws an exception.
–
Charles WoodJun 25 '14 at 16:28

@JonCoombs Java supports the subclassing and creating own method. However few classes are marked final due to certain reasons, String is one of them so we cannot extend. We can create other class and make utility class there which take two string as arguments and implement our logic there. Also for null check some other libraries like spring and apache he good collections of methods, one can use that.
–
PantherApr 12 at 5:05

This is a because when you create any String literal, JVM first searches for that literal in String pool, if it matches, same reference will be given to that new String, because of this we are getting

(a==b) ===> true

String Pool
b -----------------> "test" <-----------------a

== fails in 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 in heap that reference will be given to b, so b will be given reference in heap not in String Pool.
Now a is pointing to String in String pool while b is pointing to String in heap, because of that we are getting

String 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 that 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.

"==" means that your two string references are exactly the same object. You may have heard that this is the case because Java keeps sort of a literal table (which it does), but that is not always the case. Some strings are loaded in different ways, constructed from other strings, etc., so you must never assume that two identical strings are stored in the same location.

Java is having a String pool under which java manages the memory allocation for the String objects. See String Pools in java

What happens is when you check(compare) two objects using == operator it compares the address equality into the string-pool. If two String objects having same address references then it returns true otherwise false. But if you want to compare the contents of two String objects then you must override equals method.

equals is actually the method of Object class but is Overridden into the String class and new definition is given which compares the contents of object.

Example:
stringObjectOne.equals(stringObjectTwo);

But mind it respects the case of String. If you want Case insensitive compare then you must go for equalsIgnoreCase method of the String class.

== compares object references in Java, and that is no exception for String objects.

For comparing the actual contents of objects (including String), one must use the equals method.

If a comparison of two String objects using == turns out to be true, that is because the String objects were interned, and the Java Virtual Machine is having multiple references point to the same instance of String. One should not expect that comparing one String object containing the same contents as another String object using == to evaluate as true.

Yes, == is bad for comparing Strings (any objects really, unless you know they're canonical). == just compares object references. .equals() tests for equality. For Strings, often they'll be the same but as you've discovered, that's not guaranteed always.

== performs a reference equality check, whether the 2 objects (strings in this case) refer to the same object in the memory.

The equals() method will check if the contents or the states of 2 objects are the same.

Obviously == is faster, but will (might) give false results in many cases if you just want to tell if 2 strings hold the same text.

Definitely the use of equals() method is recommended.

Don't worry about the performance. Some things to encourage using String.equals():

Implementation of String.equals() first checks for reference equality (using ==), and if the 2 strings are the same by reference, no further calculation is performed!

If the 2 string references are not the same, String.equals() will next check the lengths of the strings. This is also a fast operation because the String class stores the length of the string, no need to count the characters or code points. If the lengths differ, no further check is performed, we know they cannot be equal.

Only if we got this far will the contents of the 2 strings be actually compared, and this will be a short-hand comparison: not all the characters will be compared, if we find a different character (at the same position in the 2 strings), no further characters will be checked.

When all is said and done, even if we have guarantee that the strings are interns, using the equals() method is still not that overhead that one might think, definitely the recommended way. If you want efficient reference check, then use enums where it is guaranteed by the language specification and implementation that the same enum value will be the same object (by reference).

If you're like me, when I first started using Java, I wanted to use the "==" operator to test whether two String instances were equal, but for better or worse, that's not the correct way to do it in Java.

In this tutorial I'll demonstrate several different ways to correctly compare Java strings, starting with the approach I use most of the time. At the end of this Java String comparison tutorial I'll also discuss why the "==" operator doesn't work when comparing Java strings.

Option 1: Java String comparison with the equals method
Most of the time (maybe 95% of the time) I compare strings with the equals method of the Java String class, like this:

if (string1.equals(string2))

This String equals method looks at the two Java strings, and if they contain the exact same string of characters, they are considered equal.

Taking a look at a quick String comparison example with the equals method, if the following test were run, the two strings would not be considered equal because the characters are not the exactly the same (the case of the characters is different):

String string1 = "foo";
String string2 = "FOO";
if (string1.equals(string2))
{
// this line will not print because the
// java string equals method returns false:
System.out.println("The two strings are the same.")
}

But, when the two strings contain the exact same string of characters, the equals method will return true, as in this example:

String string1 = "foo";
String string2 = "foo";
// test for equality with the java string equals method
if (string1.equals(string2))
{
// this line WILL print
System.out.println("The two strings are the same.")
}

Option 2: String comparison with the equalsIgnoreCase method

In some string comparison tests you'll want to ignore whether the strings are uppercase or lowercase. When you want to test your strings for equality in this case-insensitive manner, use the equalsIgnoreCase method of the String class, like this:

There is also a third, less common way to compare Java strings, and that's with the String class compareTo method. If the two strings are exactly the same, the compareTo method will return a value of 0 (zero). Here's a quick example of what this String comparison approach looks like:

While I'm writing about this concept of equality in Java, it's important to note that the Java language includes an equals method in the base Java Object class. Whenever you're creating your own objects and you want to provide a means to see if two instances of your object are "equal", you should override (and implement) this equals method in your class (in the same way the Java language provides this equality/comparison behavior in the String equals method).

String a = "This is the first string.";
String b = "this is not 1st string!";
// for exact string comparison, use .equals
boolean exact = a.equals(b);
// For similarity check, there are libraries for this
// Here I'll try a simple example I wrote
float similarity = simple_similarity(a,b);

not to be nit picky, but the equals() method for String is actually in the String class, not in Object. The default equals() in Object would not compare that the contents are the same, and in fact just returns true when the reference is the same.
–
Jacob SchoenNov 20 '12 at 17:04

== operator check if the two references point to the same object or not.
.equals() check for the actual string content(value).

Note that .equals() method belongs to Class Object(Super class of all classes). You need to override it as per you class requirement but for String it is already implemented and it checks whether two string have same value or not.

Case1)
String s1 = "StackOverflow";
String s2 = "StackOverflow";
s1 == s2; //true
s1.equals(s2); //true
Reason: String literals created without null are stores in String pool in permgen area of heap. So both s1 and s2 point to same object in the pool.
Case2)
String s1 = new String("StackOverflow");
String s2 = new String("StackOverflow");
s1 == s2; //false
s1.equals(s2); //true
Reason: If you create String object using new keyword separate space is allocated to it on heap.

You can also use compareTo() method to compare two Strings. If the compareTo result is 0, then the two strings are equal, otherwise the strings being compared are not equal.

The == compares the references and does not compare the actual strings. If you did create every string using new String(somestring).intern() then you can use the == operator to compare two strings, otherwise equals() or compareTo methods can only be used.

equals() method is present in the java.lang.Object class and it is expected to check for the equivalence of the state of objects!. That means, the contents of the objects. Whereas the == operator is expected to check the actual object instances are same or not.

Example

Consider two different reference variables str1 and str2

str1 = new String("abc");
str2 = new String("abc");

if you use the equals()

System.out.println((str1.equals(str2))?"TRUE":"FALSE");

You will get the output as TRUE

if you use ==

System.out.println((str1==str2)?"TRUE":"FALSE");

Now you will get the FALSE as output because both str1 and str2 are pointing to two different objects even though both of them share the same string content. It is because of new String() everytime a new object is created.

In Java, when the “==” operator is used to compare 2 objects, it checks to see if the objects refer to the same place in memory. In other words, it checks to see if the 2 object names are basically references to the same memory location.

The Java String class actually overrides the default equals() implementation in the Object class – and it overrides the method so that it checks only the values of the strings, not their locations in memory.
This means that if you call the equals() method to compare 2 String objects, then as long as the actual sequence of characters is equal, both objects are considered equal.

The == operator checks if the two strings are exactly the same object.

unless one of them is null, since s.equals(s2) will crash if s is null, causing the comparison to fail. Of course, this doesn't really contradict the answer; it's just a caveat.
–
Jon CoombsJun 20 '14 at 1:05

All objects are guaranteed to have a .equals() method since Object contains a method .equals() that returns a boolean. It is the subclass' job to override this method if a further defining definition is required. Without it(i.e. using ==) only memory addresses are checked between two objects for equality. String overrides this .equals() method and instead of using the memory address it returns the comparison of strings at the character level for equality.

A key note is that strings are stored in one lump pool so once a string is created it is forever stored in a program at the same address. Strings do not change, they are immutable. This is why it is a bad idea to use regular string concatenation if you have a serious of amount of string processing to do. Instead you would use the StringBuilder classes provided. Remember the pointers to this string can change and if you were interested to see if two pointers were the same == would be a fine way to go. Strings themselves do not.

"once a string is created it is forever stored in a program at the same address" - This is flat-out wrong. Only compile-time constant string expressions (possibly involving final String variables) and strings that your program explicitly interns are stored in what you call a "lump pool". All other String objects are subject to garbage collection once there are no more live references to them, just like any other type of object. Also, while immutability is required for the whole interning mechanism to work, it's otherwise irrelevant to this.
–
Ted HoppApr 10 '14 at 18:13