Win a copy of Functional Reactive Programming this week in the Other Languages forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Sets confusion

 
Meghna Bhardwaj
Ranch Hand
Posts: 109
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
HI All,
The program below, taken from K&B question 12, pg 617



I added the equals and hashCode methods, the output is:
Total Size : 3
Get : true
jane
hans
lotte
I am wondering why I get true for g.contains(p5) ?? It is a duplicate value and I AM correctly overriding
equals and hashcode so i expect to see false here instead? Any ideas?
 
Ninad Kulkarni
Ranch Hand
Posts: 802
Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi, Meghna you are using string pool reference thats why this happens.
"hans" == "hans" gives true becuase they are string literal. jvm put "hans" in string pool meaning that reference of object is store in string pool. JVM treat string literal specially.
Try using new like String("hans") etc and see what happens.
 
Bob Wheeler
Ranch Hand
Posts: 317
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If you don't override the hashCode and equals methods, you get a false for g.contains(p5). EDIT: Be careful. The last said is wrong
But you did override them. So the contains method doesn't look for the p5 object, it looks for a simular object (defined after the equals method). So it looks after an object with the same instance variable name with value "hans". And we have one, so it returns true.

cheers
Bob
 
Meghna Bhardwaj
Ranch Hand
Posts: 109
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
HI Bob,

You mention that:
If you don't override the hashCode and equals methods, you get a false for g.contains(p5).

I retested my program after commenting out the equals and hashCode methods above and the result was
g.contains(p5) is still TRUE! and as expected the total size was 5 as there is no way to compare the different
values... this is no surprise though.


 
Bob Wheeler
Ranch Hand
Posts: 317
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Meghna Bhardwaj wrote:HI Bob,
You mention that:
If you don't override the hashCode and equals methods, you get a false for g.contains(p5).

I retested my program after commenting out the equals and hashCode methods above and the result was
g.contains(p5) is still TRUE! and as expected the total size was 5 as there is no way to compare the different
values... this is no surprise though.

Oops, sorry. Sure, you are right. But my explanation is still valid ( I hope ):
The contains method doesn't look for the p5 object in the HashSet, it looks for a similar object (defined after the equals method). So here it looks after an object with the same instance variable name with value "hans". And we have one, so it returns true.
 
Ruben Soto
Ranch Hand
Posts: 1032
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The key points here are:

- Given the implementation of your equals() method, the objects pointed to p3 and p5 are equal because their name String instances point to exactly the same object in the heap (this is due to the fact that you use String literals for the arguments of the Person constructor.) Try to instantiate p5 using new String("jane") as the argument instead, and see what you get.
- Even though you get the output which indicates that p5 is in the set, that doesn't mean that the object pointed to by p5 was added to the set. Actually it wasn't. What it means is that a object equal to the one pointed to by p5 was added to the set (in this case p3.) You can test this by augmenting the Person class with an additional instance variable which doesn't affect the hashCode() or equals() values, setting it differently for p3 and p5, and then testing the value after retrieval from the set.
- You should change your equals() method to use the String.equals() method instead of the == operator. The equals() method is checking for logical equality, and to have the equals() result differ on whether you instantiate an object using a String literal or a newly instantiated String object is bound to create problems.
 
Ninad Kulkarni
Ranch Hand
Posts: 802
Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi, Meghna
You read this for String pool concept.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic