File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes equals() and == Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "equals() and ==" Watch "equals() and ==" New topic
Author

equals() and ==

Nabila Mohammad
Ranch Hand

Joined: Nov 05, 2007
Posts: 661
Can some one tell me the difference with an example or an illustration-Which one is used and when?
Thnks.


The future belongs to those who believe in the beauty of their dreams.Dream BIG!
R van Vliet
Ranch Hand

Joined: Nov 10, 2007
Posts: 144
Hi Nabila,

First of all, the difference is only relevant for objects (descendants of the Object class).

Now, the equals() method does nothing more than allow objects to override the default comparison. The code for Object's own equals() method is actually something like :



So by default there is no logical difference. However, subclasses of Object (which are all classes in Java) can override this method to provide more relevant/appropriate object comparison.

Consider for example the String object. If you would make two strings :



Then you're looking at two different String instances, but their content is actually the same, so in the case of the String class, the equals() method is overridden and compares string content rather than use the default approach, which is checking if they are the same object instance. So



Would return false, because s1 is not the same object as s2, but



would return true, because s1 and s2 hold the same content. Similarly for classes like Integer the integer values are compared, and more complex objects might have more complicated implementations of equals().

So to recap, consider it a way to override the standard way to compare to objects, which is to check if both objects involved in the comparison are the same instance :



Hope that helped.
[ November 20, 2007: Message edited by: R van Vliet ]
R van Vliet
Ranch Hand

Joined: Nov 10, 2007
Posts: 144
I'll add that mixing the two up is actually a very common source of bugs amongst less experienced developers, i recall quite a few instances where we tracked a bug down to code like :

Fu Dong Jia
Ranch Hand

Joined: May 23, 2007
Posts: 131
hi!

== operator evaluates to true only when both references refer to the same object.because == simply looks at the bits in the variable, and they're either identical or they're not.
You saw that the String class and the wrapper classes have overridden
the equals() method (inherited from class Object), so that you could compare
two different objects (of the same type) to see if their contents are meaningfully equivalent.When you really need to know if two references are identical, use ==.

for example:

the output is:
false
true




who dare win!<br />SCJP5(94%)|SCWCD5(86%)|SCBCD(100%)|SCEA in progress
Kelvin Chenhao Lim
Ranch Hand

Joined: Oct 20, 2007
Posts: 513
Adding on to the previous posts, you may also find it helpful to remember that when o1 == o2, then o1.equals(o2) is always true (if equals is implemented correctly). However, the converse isn't always true, i.e. when o1.equals(o2) == true, o1 need not be == to o2.
[ November 20, 2007: Message edited by: Kelvin Lim ]

SCJP 5.0
Luca Romanello
Greenhorn

Joined: May 30, 2002
Posts: 11
Originally posted by R van Vliet:




Hi all
I respectfully disagree with your example. All boolean tests return true, since assigning String literal to String variables means that the jvm take advantage of its String constant pool - so s1 and s2, though both initialized without referencing each other, point to the same object (String) in the pool.
The example made by Fudong is correct, since both str1 and str2 make an explicit call to String constructor, creating two new (and different) instances.
We can find the same (or - better - very similar) behaviour working with int literals in short range (between -128 and 127; even if assigning them to a wrapper via boxing should mean making a new constructor call ):

will print true, while assigning 128 to s1 and s2 will print false.
Hope this helps.
Regards
LR
[ November 20, 2007: Message edited by: Luca Romanello ]
Dee-Jay
Greenhorn

Joined: Nov 20, 2007
Posts: 3
Thanks LR. That was an excellent reply.


The Race is not yet over; Because i have not yet won!!
R van Vliet
Ranch Hand

Joined: Nov 10, 2007
Posts: 144
Originally posted by Luca Romanello:


Hi all
I respectfully disagree with your example. All boolean tests return true, since assigning String literal to String variables means that the jvm take advantage of its String constant pool - so s1 and s2, though both initialized without referencing each other, point to the same object (String) in the pool.
The example made by Fudong is correct, since both str1 and str2 make an explicit call to String constructor, creating two new (and different) instances.
We can find the same (or - better - very similar) behaviour working with int literals in short range (between -128 and 127; even if assigning them to a wrapper via boxing should mean making a new constructor call ):

will print true, while assigning 128 to s1 and s2 will print false.
Hope this helps.
Regards
LR

[ November 20, 2007: Message edited by: Luca Romanello ]



Hi Luca,

I stand corrected, I oversimplified my example and you are right that that evaluation will indeed return true (on a slightly pedantic note, i do believe it should return false, only object variables explicitly set to refer to another object should return true, this happening as the result of a VM constant pool optimization seems questionable, but it's a tradeoff that can be defended).

I've modified the example to actually work as described
Kelvin Chenhao Lim
Ranch Hand

Joined: Oct 20, 2007
Posts: 513
Originally posted by R van Vliet:
(on a slightly pedantic note, i do believe it should return false, only object variables explicitly set to refer to another object should return true, this happening as the result of a VM constant pool optimization seems questionable, but it's a tradeoff that can be defended).


Actually, this string constant interning behavior is mandated by the JVM spec, so the comparison will always return true. It's not an implementation-specific optimization.
Nabila Mohammad
Ranch Hand

Joined: Nov 05, 2007
Posts: 661
Thanks guys.That was a big help!
Take care.
Cameron Wallace McKenzie
author and cow tipper
Saloon Keeper

Joined: Aug 26, 2006
Posts: 4968
    
    1

This is always a big topic with people new to Java.

I always use my car as an example. If I see another car on the road that is the same make, model, color and trim as my car, I think that other car .equals() my car, and I admire it.

On the other hand, if I see a car that is the same make, model, color and trim as my car, and some shady character is in the drivers seat, I'm not doing a .equals() comparison. I want to see if the car in question is == to MY car. If it is, that shady character is stealing MY car.

I put together a little test to help people out on the topic. It's also a good little mock exam if you're doing the SCJA or SCJP exam. The questions reinforce the idea, and there's a spot on the page where you can click and drag and actually see the answer. Give it a try!

Questions to Help Understand == , .equals() and jsut plain old =

Kind regards!

-Cameron McKenzie
Nabila Mohammad
Ranch Hand

Joined: Nov 05, 2007
Posts: 661
I have a doubt.
In the following code :

MyClass obj1=new MyClass();
MyClass obj2=new MyClass();

obj1=obj2;

In this case both of the following is true,I am not sure why.
1. obj1==obj2
2. obj1.equals(obj2)


Can you tell me when the first case will be false and the other true and vice versa .
Which one is comparing the instance and what is the function of the other one?
Nabila Mohammad
Ranch Hand

Joined: Nov 05, 2007
Posts: 661
Hey Cameron,
That link you gave me is Awsome!
Thanks alot for it.
Do you have more like it?
Tc.
nico dotti
Ranch Hand

Joined: Oct 09, 2007
Posts: 124
Someone correct me if I'm wrong as I'm by no means an expert (yet!):
Using your example

If you did the obj==obj2 test here (before the next line) the result will be false as obj1 and obj2 'refer' to different objects. But when you do this:


And here's a complete program you can compile as bar.java (You'll have to get rid of the line numbers of course!

nico dotti
Ranch Hand

Joined: Oct 09, 2007
Posts: 124
Originally posted by nico dotti:
Someone correct me if I'm wrong as I'm by no means an expert (yet!):
Using your example Nabila:

If you did the obj==obj2 test here (before the next line) the result will be false as obj1 and obj2 'refer' to different objects. But when you do this:

ojb1 doesn't refer to the object it used to (obj1...itself), it now refers to obj2! So now the are referring to the same object and the '==' will evaluate to true.

And here's a complete program you can compile as bar.java which should resolve any doubts.

Nabila Mohammad
Ranch Hand

Joined: Nov 05, 2007
Posts: 661
I got the "==" part
How about the equals() part..?
Nabila Mohammad
Ranch Hand

Joined: Nov 05, 2007
Posts: 661
The following program has no ouptut.
Can someone tell me why?

Luca Romanello
Greenhorn

Joined: May 30, 2002
Posts: 11
Originally posted by Nabila Mohammad:
I got the "==" part
How about the equals() part..?


Hi Mohammad
Both "==" and equals() will return false BEFORE assigning obj2 to obj1, unless class MyClass overrides the inherited (from Object) method equals() so to make it return true. If MyClass doesn't override it, the jvm will use Object's equals() which will run a "==" test:

This is the same reason why testing AFTER assigning obj2 to obj1 will return true in both cases (being a) the same instance and b) basically the same test). The key here is whether method equals() has or hasn't been overridden.

Edit: as for your last post, no output is shown just because of the same reason, method equals() wasn't overridden, so both "==" and equals() will return false, being two different references and two different instances. If you overrides method equals() this way:

then the main will print out "look at that pretty car.", 'cause equality will be tested against Car's member model and not against object reference...
Hope this helps
Regards
LR
[ November 21, 2007: Message edited by: Luca Romanello ]
Nabila Mohammad
Ranch Hand

Joined: Nov 05, 2007
Posts: 661
That helps alot.
Thanks!
Luca Romanello
Greenhorn

Joined: May 30, 2002
Posts: 11
Hi all
I previously (here and maybe in another thread) stated that short range was between -128 and 127. This is an error I deeply apologize for: that range is byte's and not short's.
Sorry
Regards
LR
nico dotti
Ranch Hand

Joined: Oct 09, 2007
Posts: 124
Just another wrinkle. In your example:

Like the other poster said, the Car class would need to implement an equals method to determine if two instances of Cars are 'meaningfully' equal. However, certain built in java classes like String, Enum, etc., have implemented the equals method for you already! So if you're code above was changed to:

your output will be: look at that pretty car. So if you have any custom classes (like a Car object), and you want to be able to compare for 'meaningful equality', you need to create an implementation of equals which should test that the Object passed in is an instanceof the custom class (ie o instanceof Car), and then compares some meaningful field(s). So you may compare the vehicles VIM number, or you may feel that's not thorough enough, and decide that it has to have the same VIM, owner registration, license, etc., it's up to you. I hope this doesn't confuse you more...the main 'gist' of what I'm trying to point out is that sometimes you can use built in equals functionality and sometimes you need to do it yourself.
ayan basuu
Greenhorn

Joined: Dec 04, 2007
Posts: 4
Hi when I am writing the code :
String s1 ="abc";
String s2 ="abc";
System.out.println(s1==s2);
System.out.println(s1.equals(s2));
It's printing
true
true
But when I am writing
String s1 =new String("abc");
String s2 =new String("abc");
System.out.println(s1==s2);
System.out.println(s1.equals(s2));
It's is printing
false
true
Could you please explain the reason behind it?


Never explain yourself to anybody
Pranav Bhatt
Ranch Hand

Joined: Mar 20, 2006
Posts: 284
Ayan,
In java there is a concept of String constant pool to save memory.If you create a string object as String s1="aaa"; this creates a object with reference variable s1. But if again you give String s2="aaa"; this wont create a new object, infact the variable s2 will refer to the same object in the constant pool in order to save memory. But if you created them with new keyword as in your 2nd example you get 2 different objects with same contents.
Here in your 1st example
String s1 ="abc";
String s2 ="abc";

You created one object with s1 as reference, but when you write String s2 ="abc"; here another reference variable s2 refers to the same object of s1

In your second example-:
String s1 =new String("abc");
String s2 =new String("abc");

you have used "new" so this will give you two different objects with same contents.

And as per the discussion above you can see that as Strings have overidden the equals method, so will give true only if the object contents are equal, whereas == will be true if the references will refer to same object.
Hope this clears the doubt
thanks
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: equals() and ==