Wednesday, January 30, 2008

String comparisons : == vs. equals()

It is a well known that you cannot compare two objects obj1 and obj2 using == operator. == operator checks for the equality of the references not the equality of the objects. Just a little snippet is shown below

Point p1 = new Point(100,100);
Point p2
= new Point(100,100);
System.out.println(p1
==p2); // ??
The above code snippet, when run, displays "false" in the output console. But still both p1 and p2 refers to a coordinate (100,100). So if you wish to get your equality to be true for such cases (where the object content! matches), then you should be using "equals()" method. This works for almost all the classes shipped with JDK. For this to work on the objects of the classes that you write (eg: Employee class or Chair or Bench.java), then you should override the method "public boolean equals(Object two)" and implement your meaning of equality of the objects of your class. Also note that, it is highly recommended and important that you override the "int hashCode()" method when you override the "equals" method.

Anyway, now when we deal with String comparisons, one should remember that "Strings" are not value types but are reference types (I mean String is a class). So Strings have to compared for equality using equals method instead of == operator. But the way the JVM is implemented, there are cases under which the == returns true for matching strings. So what are the cases?

Case 1: Where == returns true

String s1 = "Krishna";
String s2 = "Krishna";
if(s1==s2)
System.out.println("Strings are equal!!");
else
System.out.println("You cannot use == here");

Trying running the code as it is and you see the "Strings are equal" on the console. Well can you guess why?

The reason for the == operator to work in this case is that the Java compiler optimizes the strings s1 and s2. Since they are both "initialized" to "Krishna", instead of having two different string objects, optimization is done by having only one object and both s1 and s2 refer to the same "Krishna" object. Remember that the == operator only works for "static" kind of initialization. So if it was the case where s1 = new String("Krishna"); then s1 == s2 would return false instead of true, though it appears both are being initialized to the same "Krishna". Let us see another case where s1 == s2 fails.

Case 2: Where == returns false and equals() return true

String s1 = "Krishna";
String s2 = new String(s1);
if(!(s1==s2))
System.out.println("You cannot use == here");
else if(s1.equals(s2))
System.out.println("You should use 'equals' method in all cases");
Anyway the moral of the story is that you should always use "equals" to compare strings and should never use == even though it works in few cases.

No comments: