• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

equals() and ==

 
Ranch Hand
Posts: 664
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Can some one tell me the difference with an example or an illustration-Which one is used and when?
Thnks.
 
Ranch Hand
Posts: 144
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 144
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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 :

 
Ranch Hand
Posts: 131
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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


 
Ranch Hand
Posts: 513
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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 ]
 
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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 ]
 
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks LR. That was an excellent reply.
 
R van Vliet
Ranch Hand
Posts: 144
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 513
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 664
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks guys.That was a big help!
Take care.
 
author and cow tipper
Posts: 5009
1
Hibernate Spring Tomcat Server
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 664
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 664
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hey Cameron,
That link you gave me is Awsome!
Thanks alot for it.
Do you have more like it?
Tc.
 
Ranch Hand
Posts: 124
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 124
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 664
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I got the "==" part
How about the equals() part..?
 
Nabila Mohammad
Ranch Hand
Posts: 664
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The following program has no ouptut.
Can someone tell me why?

 
Luca Romanello
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 664
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
That helps alot.
Thanks!
 
Luca Romanello
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 124
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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?
 
Ranch Hand
Posts: 284
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
reply
    Bookmark Topic Watch Topic
  • New Topic