File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Beginning Java and the fly likes String comparison styles in equals Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of EJB 3 in Action this week in the EJB and other Java EE Technologies forum!
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "String comparison styles in equals" Watch "String comparison styles in equals" New topic
Author

String comparison styles in equals

M Berg
Greenhorn

Joined: Sep 01, 2010
Posts: 13
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

Joined: Apr 06, 2010
Posts: 4240
    
    7

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

Joined: Aug 30, 2010
Posts: 147

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.

OCPJP
In preparing for battle I have always found that plans are useless, but planning is indispensable. -- Dwight D. Eisenhower
Kushan Athukorala
Ranch Hand

Joined: Aug 09, 2010
Posts: 33
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


Kushan Athukorala
OCPJP 6.0 [86%]
Alex Hurtt
Ranch Hand

Joined: Oct 26, 2010
Posts: 98
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

Joined: Oct 27, 2005
Posts: 19541
    
  16

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.


SCJP 1.4 - SCJP 6 - SCWCD 5 - OCEEJBD 6
How To Ask Questions How To Answer Questions
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 36478
    
  16
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

Joined: Sep 20, 2010
Posts: 3370
    
    9
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

Joined: Aug 09, 2010
Posts: 33
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

Joined: Apr 06, 2010
Posts: 4240
    
    7

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

Joined: Oct 13, 2005
Posts: 36478
    
  16
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?
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: String comparison styles in equals
 
Similar Threads
Primary Key class?
Arraylist insights
Using the equals and Hashcode methods of an Object?
StackOverflowError in hashCode due to recursion
Comparator doubt