views:

3101

answers:

11

I've been using the "==" operator in my program to compare all my strings so far. However, I ran into a bug, changed one of them into .equals() instead, and it fixed the bug.

Is "==" bad? When should it and should it not be used? What's the difference?

Thanks

+37  A: 

== tests for reference equality.

.equals tests for value equality.

Consequently, if you actually want to test whether two strings have the same value you should use .equals (except in a few situations where you can guarantee that two strings with the same value will be represented by the same object eg: String interning).

== is for testing weather two strings are the same object.

// 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 

It is important to note that == is much cheaper than equals (a single pointer comparision instead of a loop), thus, in situations where it is applicable (ie. you can guarantee that you are only dealing with interned strings) it can present an important performance improvement; however, these situations are rare.

Aaron Maenpaa
I guess in Java you should say "references" instead of "pointers".
Henrik Paul
"Reference equality" just doesn't sound as good as "Pointer equality", though you might be right.
Aaron Maenpaa
If you can do things this way, what is the method compareTo useful for?
Xokas11
@Xokas11: compareTo is generally used for sorting.
Michael Myers
equals, compareTo and hashCode are all directly related with contracts that must be fulfilled. Only equals and hashCode are polymorphic over all objects. compareTo is from Comparable.
pst
Regarding your last note - one should *never* use == with strings, even interned once, since it makes your code fragile if a string ever, for some unrelated reason, becomes un0interned - you're effectively coupling the semantics of the comparison to the semantics of creation. The first thing an equals call does is a test for reference equality anyway, so you dont lose any performance benefits by using it.
Visage
A: 

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

cletus
+1  A: 

== 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.

coobird
+2  A: 

Yea, it's bad...

"==" 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.

Equals does the real comparison for you.

Uri
+1  A: 

.equals compares the data in a class (assuming the function is implemented). == compares pointer locations (location of the object in memory)

== returns true if both objects (NOT TALKING ABOUT PRIMITIVES) point to the SAME object instance .equals returns true of two objects contain the same data

http://www.java-samples.com/showtutorial.php?tutorialid=221

That may help you.

Mr. Pig
+2  A: 

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.

Clayton
A: 
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.

duffymo
+4  A: 

"==" 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
nullString1 == nullString2;

// Throws an Exception
nullString1.equals(nullString2);
Whatsit
A: 

I agree with the answer from zacherates.

But what you can do is to call intern() on your non-literal strings.

From zacherates example:

  // ... but they are not the same object
  new String("test") == "test" ==> false

If you intern the non-literal String equality is true

  new String("test").intern() == "test" ==> true
pgras
A: 

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.

Faisal Feroz