• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

String comparison styles in equals

 
M Berg
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi, please see the code below. There are two styles to override equals, both are working.

Need an expert opinion on small detail: as name is String in BParent, should I prefer use
String.equals() instead of "==" in order to compare key String values within Object's overridden equals method?
I am aware of the String Pool but don't really get my book's idea on comparing two Strings with "==".




Many thanks,
Kind regards MB
 
Matthew Brown
Bartender
Posts: 4567
8
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
For Strings I would always use equals() rather than ==. == will sometimes work, depending on the implementation details, but you can't guarantee it (and in some circumstances it can be guaranteed not to work).
 
Pete Nelson
Ranch Hand
Posts: 147
Debian Eclipse IDE Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In java, the equals operator (==) when applied to objects looks to see if both references point to the same object. The String's equals(String) method on the other hand checks to see if the character sequence is the same



Only the equals(String) method truly checks if the contents of the String match.
 
Kushan Athukorala
Ranch Hand
Posts: 33
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Pete,

a==c also returns true. To explain this we have to consider the String Constant Pool.

It is a part of memory area defined specially for Strings. Whenever you create different strings it is added to the pool but if you define same strings, it doesn't create new strings but take the string from the pool memory. So the a==c should return true in your explanation.

Thanks,
Kushan

 
Alex Hurtt
Ranch Hand
Posts: 98
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Kushan Athukorala wrote:Hi Pete,

a==c also returns true. To explain this we have to consider the String Constant Pool.

It is a part of memory area defined specially for Strings. Whenever you create different strings it is added to the pool but if you define same strings, it doesn't create new strings but take the string from the pool memory. So the a==c should return true in your explanation.

Thanks,
Kushan



No. Use equals(). Don't program according to what "should" happen. Program by what is guaranteed to work. If you want to test for object equality based on whether or not 2 objects have a reference to the same single String object, then by all means use == for your comparison. But I doubt that is what you want. All you really probably care about is whether or not the VALUES of the strings referenced by the 2 objects are identical. In this case you should use equals().

It is a simple matter to disprove Kushans advice. Make a little test class and put the following in your main() method and see what the variables 'areEquivalent' and 'areEqual' evaluate to:

String s1 = "astringval";
String s2 = new String("astringval");
String s3 = "astringval";
boolean areEuivalent = s1 == s2; //false
boolean areEqual = s1.equals(s2); //true
boolean areTheseEqual = s1 == s3; //probably true ...maybe...but not 100% iron-clad guaranteed. Not safe defensive programming style.
boolean howAboutThese = s1.equals(s3); //true

Since you can't guarantee that the person calling your equals() method didn't construct a String object in such a way as above by using the new keyword, it is unsafe to assume that '==' will always give you the desired result...unless, as I said, reference equality is really what you care about, not value equality.

Also, as a side note, keep in mind that since the first rule of the equals() contract states that equals() should be reflexive, you may automatically return true any time obj==this.
 
Rob Spoor
Sheriff
Pie
Posts: 20546
56
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Kushan wasn't suggesting that == should be used. He (or she? I don't really know...) merely corrected Pete's incorrect statement that a == c would return false.
 
Campbell Ritchie
Sheriff
Pie
Posts: 49367
62
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
When I did my MSc Java™ assessment, one person who came from a C# background (where == is overloaded for Strings) used == on Strings. It worked all right (because he was using compile-time constant Strings, and they were all in the String pool) until he serialised and deserialised some objects; then all their String references pointed to different objects and the whole application failed to work.
 
Stephan van Hulst
Bartender
Pie
Posts: 5889
63
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Unless testing for identity, you should always use equals to compare two objects, unless the class guarantees that no two nonidentical instances will be equal. Enums are such a case. You can always compare enum instances with ==.
 
Kushan Athukorala
Ranch Hand
Posts: 33
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Alex,

I would like to clear some of your misunderstanding on Java concepts.

Case I :

'==' is and operator in java. This operator internally use the equals() method which is defined in Object class to compare whether the two object references are pointing to the same object instance.

If you define Strings as in Case I above, you are creating one "Hello" string in the String Constant Pool Memory with two s1 and s2 references. This is merely because of performance reasons in java.

This is the reason why you see the '==' operator gives the 'true' result on comparison.

Case II:

'equals()' is an method define in Object class. This method can be used to compare the two objects for meaningful equivalence. If you want to make two objects be meaningfully equal you have to override the equals() method in your class.

If you use 'new' to define a String, such strings will be created on heap memory, not in the pool memory. Therefore you can see two s1, s2 references pointing to two String objects in the heap. This is the reason why you see '==' operator giving 'false' on comparison in this scenario.

Then the question is why you get equals() comparison 'true' in such circumstances.

Let me explain.

As I mentioned earlier equals() method of Object class can be override to check for meaningful equivalence. The developer who did code the String class for us, has been overridden the equals() method so that we can see two String objects are meaningfully equivalent.

I hope now everything is clear to you.

Thanks,
Kushan

 
Matthew Brown
Bartender
Posts: 4567
8
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Kushan Athukorala wrote:
'==' is and operator in java. This operator internally use the equals() method which is defined in Object class...

No, it doesn't. The operator doesn't use any methods. In fact, it's the other way around: the Object.equals() method uses == internally.

Apart from that, you haven't said anything that disagrees with Alex, who appears to understand it fine. His point was that you shouldn't rely on the string constant pool, as that means you're relying on implementation specific details that may not always work. Whereas the equals() method is guaranteed always to follow the contract.
 
Campbell Ritchie
Sheriff
Pie
Posts: 49367
62
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Kushan Athukorala wrote:. . . you are creating one . . . string in the String Constant Pool . . . This is merely because of performance reasons in java. . . .
Are you sure performance is the reason for that?
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic