• Post Reply Bookmark Topic Watch Topic
  • New Topic

== and .equals()  RSS feed

 
sai rama krishna
Ranch Hand
Posts: 536
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I read as below

.equals() method present in object class also meant for reference comparison only based on our requirement we can override for content comparison.(i thought == do reference comparison not .equals() method???)
In String class, all wrapper class and all collection classes .equals() method is overridden for content comparison.

String s1= new String("john")
String s2= new String("john")////as attached in picture. So by not seeing picture, we cannot say both s1, s2 refer to same john object or different john object(which is case here)??



String s3= new String("mike")
String s4= new String("mike")//as attached in picture. So by not seeing picture we cannot say both s3, s4 refer to same mike object(which is case here) or different mike object??



s3==s4 is true since both refer to same object.(since both refer to same object obviously content is same right. so by default in case of String if == is true then .equals() always true right??
Does this behaviour change with StringBuilder, Custom Object, string Buffer etc


please advise
-.png
[Thumbnail for -.png]
 
Tim Cooke
Marshal
Posts: 4051
239
Clojure IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
We have a nice little Wiki article all about this topic: AvoidTheEqualityOperator
 
Campbell Ritchie
Marshal
Posts: 56599
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Part 1 Correct. As you said, s1 == s2 returns false because they are different objects.
So how is part 2 any different from part 1? How do you manage to get different results from part 1 when you have the same code?
Have you tested it?What about StringBuilder (don't use StringBuffer)? What does it say about its equals() method in its documentation?

[edit]I had missed out returns false[/edit]
 
Jesper de Jong
Java Cowboy
Sheriff
Posts: 16060
88
Android IntelliJ IDE Java Scala Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
sai rama krishna wrote:.equals() method present in object class also meant for reference comparison only based on our requirement we can override for content comparison.(i thought == do reference comparison not .equals() method???)

When the sentence says is that the .equals() method of class java.lang.Object just uses ==, so that if you do not override equals() in your own class, it will use the version that is in class java.lang.Object, which does the same as ==.

sai rama krishna wrote:So by not seeing picture, we cannot say both s1, s2 refer to same john object or different john object(which is case here)??

s1 and s2 refer to different String objects, you don't need the picture to see that. Whenever you use new you create a new object. You used new twice here, so you have two different objects.

sai rama krishna wrote:So by not seeing picture we cannot say both s3, s4 refer to same mike object(which is case here) or different mike object??

This is exactly the same as your first example and the picture is wrong. You used new two times, so you have two different objects.

sai rama krishna wrote:s3==s4 is true since both refer to same object.(since both refer to same object obviously content is same right. so by default in case of String if == is true then .equals() always true right??

No, s3 == s4 is not true, because you created two separate String objects:
sai rama krishna wrote:
String s3= new String("mike")
String s4= new String("mike")

If a == b is true, then a.equals(b) will always be true, no matter the type of object - unless somebody implemented the equals() method in a really strange and wrong way.
 
sai rama krishna
Ranch Hand
Posts: 536
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
s1 and s2 refer to different String objects, you don't need the picture to see that. Whenever you use new you create a new object. You used new twice here, so you have two different objects.


This is clear to me.

This is exactly the same as your first example and the picture is wrong. You used new two times, so you have two different objects.

This also clear to me now.
 
sai rama krishna
Ranch Hand
Posts: 536
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator


i got below output.


s3.equals(s4): true
s3 == s4: false

since s3 and s4 refer(different addresses) to different objects (eventhough same content) it gave false for ==

s3 and s4 refer to different objects(as same content) so .equals() gave true as above. Please correct me if my understanding is wrong
 
sai rama krishna
Ranch Hand
Posts: 536
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
So how is part 2 any different from part 1? How do you manage to get different results from part 1 when you have the same code?
Have you tested it?


so my part 2 (part 2 picture)comes when i do like below right

String s3=new String("mike");
String s4=null;
s3=s4;



i got NPE
Exception in thread "main" java.lang.NullPointerException
at EqualsEx.main(EqualsEx.java:14)


 
Henry Wong
author
Sheriff
Posts: 23295
125
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
sai rama krishna wrote:
since s3 and s4 refer(different addresses) to different objects (eventhough same content) it gave false for ==

s3 and s4 refer to different objects(as same content) so .equals() gave true as above. Please correct me if my understanding is wrong



Read Jesper's response again. I think that he is right, and you are taking the quote out of context. The context is likely related to inheriting from the Object class, and not the use of the String class.

Henry
 
sai rama krishna
Ranch Hand
Posts: 536
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
when i corrected my mistake as below


which matches part2 diagram right. i got below output

s3.equals(s4): true
s3 == s4: true


i understand why s3.equals(s4): true but

i did not understand why s3 == s4: true(i though both s3 and s4 (are different addesses) in second part of diagram eventhough it points to same mike object? i guess my confusion is what is reference(address) how it is related to actual mike object
please advise
 
Campbell Ritchie
Marshal
Posts: 56599
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
No, you are still wrong. The first bit about == was correct, but you completely misunderstood the equals() method. Start by reading about it here. Notice that is says it is reflexive, and note what that means. The String#equals() method is correctly overridden, so it must obey reflexivity. It also returns true if the argument is a String with the same “content”.Because of the way the compiler handles Strings, the "Campbell" on line 1 and the "Campbell" on line 2 are the same object.
 
Henry Wong
author
Sheriff
Posts: 23295
125
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
sai rama krishna wrote:
i got NPE
Exception in thread "main" java.lang.NullPointerException
at EqualsEx.main(EqualsEx.java:14)


Well, of course. You can't dereference a null reference to call an instance method. Doing so will get you a NPE at runtime.

Henry
 
Campbell Ritchie
Marshal
Posts: 56599
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You have changed the question. That is different from what you posted at first, and it is not surprising you are getting different answers.
 
Campbell Ritchie
Marshal
Posts: 56599
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You can always tell whether a class overrides the equals method by looking at its documentation.
 
sai rama krishna
Ranch Hand
Posts: 536
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It's a rare day indeed that we don't get some question about '==' on these forums, especially as it relates to Strings.
Personally, I blame the SCJP/OCJP exams, which still, after all this time, contain questions designed to test your knowledge of Java's String pool; this despite the fact that once you've passed the exam, you will probably never need it again.

The first thing to know is that the SCJP exam is not about good programming; it's about understanding the Java compiler. In fact, most of the code examples written for the exams could be cited as examples of BAD programming, so my advice to you is to forget them the second you walk out of the exam room.

And the first thing to forget is using '==' to compare references.

There are three, and only three, reasons for using '==' in the Java language:

For comparing primitives (and a String is NOT a primitive).
For comparing a reference or expression with null.
For seeing if two references or expressions refer to the exact same object, or both are equal to null ('null == null' evaluates to true).
In the first two cases, the language forces you to use '=='; but, apart from the exceptions listed at the end of this document (and there are only two), situations requiring option 3 are extremely rare. In 12 years of writing Java, I can still count the number of times I've needed a true identity comparison for regular objects on the fingers of both hands. [1]

So what should you use instead?

equals()...ALWAYS.

No "if"s, no "but"s, no "what about my particular tortured situation"s...ALWAYS.

Get out of the habit of writing '=='. Especially with Strings.

Why?

Because a correctly written equals() method will have an '==' check as its first line of code, that's why.

"But what about that String pool?", I hear you ask.

FORGET ABOUT IT.

I'd rather see a program littered with:

String myString = new String("some literal");
than a single instance of:
if (myString == someOtherString) { ...
The fact is that the first of those two statements should be:

String myString = "some literal";
but getting it wrong is far less likely to cause you any problems than using that second statement even once.
And the same is true of ALL Java wrapper classes (Integer, Long, Character, Double, Float, Byte, Short and Boolean)...indeed all Java objects.

DON'T USE '==' unless you're forced to.

By all means, read up about the String pool, or indeed the internal caches used by the other classes listed above, but don't use '=='.

GOT IT?


So when Strings come into picture i should blindly avoid == and use only .equals()


 
sai rama krishna
Ranch Hand
Posts: 536
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Instead of String if i have say Employee object as attached then the behaviour changes right.

Since String checks in the pool if there is already john created in String pool s2 object reference refers to same memory address of the same john object so == returns false in first digram case right.

where as for Employee object s1 and s2 memory references points to different memory address of different john object so == false
-Employee.jpg
[Thumbnail for -Employee.jpg]
emp
 
Jesper de Jong
Java Cowboy
Sheriff
Posts: 16060
88
Android IntelliJ IDE Java Scala Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
No...

When you use new, you are always creating a new object. This is true for String, and for any other type of object. So, if you do this:

Then you will get two distinct String objects, because you used new two times. So, s1 == s2 is false, because s1 and s2 do not refer to the same String object. The string pool has nothing to do with this.

However, when you do this (note the difference with above!):

Then s3 and s4 will be pointing to the same String object, and there will be only one String object. That is because for string literals, such as "mike", Java creates only one object, which is shared in all the places where you use the same literal. (That shared String object will be in the string pool).

Remember: When you use new, a new object is always created.
 
Campbell Ritchie
Marshal
Posts: 56599
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
sai rama krishna wrote: . . . So when Strings come into picture i should blindly avoid == and use only .equals()
It is not a case of “blindly”. you should understand what the operator and what the equals method do. You should read the documentation and see what it says about equals(). Then you will see and not be blind.

Then use the == operator under these five circumstances:
  • 1: When comparing primitives.
  • 2: When either of the operands is an enum constant.
  • 3: When either of the operands is the null literal (this is the one place where you will want to use !=, too).
  • 4: When writing equals() methods.
  • 5: When you are not writing real code but only want to find out what happens if...
  • As the quote (which looks like Winston's avoid the == operator FAQ) says, you hardly ever need to know whether you really have two references to the same object.
     
    Campbell Ritchie
    Marshal
    Posts: 56599
    172
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    sai rama krishna wrote:Instead of String if i have say Employee object as attached then the behaviour changes right. . . .
    That post is confusing, but the behaviour does not change. Employee objects might not be cached, and you might not have overridden equals() correctly, but apart from that there is no difference. Your post appears to show you do not understand what equals() and == do.
     
    Liutauras Vilda
    Sheriff
    Posts: 4928
    334
    BSD
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    sai rama,

    You'll understand these things naturally, a bit later, once you'll get better understanding about OO concepts.

    At the moment probably enough for you to know, that, when you compare primitives use "==". 2 == 2 TRUE.
    When you compare Strings, use "equals()" only. "Java".equals("Java") TRUE. String == String (think about it as FALSE at the moment).

    Move on towards something more important, as reading OO concepts for instance, and you'll get understanding about it.

     
    sai rama krishna
    Ranch Hand
    Posts: 536
    1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    This all making more sense to me.

    I mean to say as below relating to custom objects like Employee


    Any one good book which explain these practical concepts and collection, threads related core java concepts in detail and clear apart from head first java which is bit confusing being different back ground i cannot relate and understand some examples there. please advise
     
    Campbell Ritchie
    Marshal
    Posts: 56599
    172
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    The principles are exactly the same for any class, except that String and some of the wrapper classes around primitives cache instances.
     
    sai rama krishna
    Ranch Hand
    Posts: 536
    1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I agree.
    I am currently reading this paper which i like. It also refers to few other papers specifically on string and HashTable etc
    http://javapapers.com/core-java/hashcode-and-equals-methods-override/
     
    Campbell Ritchie
    Marshal
    Posts: 56599
    172
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    That paper is full of errors and poor code, I am afraid.
     
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!