• Post Reply Bookmark Topic Watch Topic
  • New Topic

Problem in HashSet  RSS feed

 
P Malhotra
Greenhorn
Posts: 7
MyEclipse IDE Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi everyone

Why this is program is giving me this output([Falcon@e48e1b]) if
I am passing the same object and overriding equals method.
Like first it will check the hashcode if the hashcode is same than the equals method
so the hashcode of the Falcon's object is same but its still not calling the equals method.

Output is : [Falcon@e48e1b]
 
Paul Clapham
Sheriff
Posts: 22835
43
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
One of the rules for hashCode and equals is this:
If a.hashCode() == b.hashCode() is true then a.equals(b) must be true

Your class doesn't follow this rule; hs.hashCode() == hs.hashCode() is naturally true, but hs.equals(hs) is false. Therefore using an object of your class in a Set or a Map may lead to unexpected results.

Your class also breaks one of the rules of equals, which is that x.equals(x) must always return true.
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Paul Clapham wrote:One of the rules for hashCode and equals is this:
If a.hashCode() == b.hashCode() is true then a.equals(b) must be true


Er... You wanna rethink that wording?
 
Campbell Ritchie
Marshal
Posts: 56578
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That is a pretty dreadful equals method, which fails to maintain the general contract for equals(), and will guarantee your set will never work. You will find some useful links in this old post.
You also have a question about an output which is completely different from your thread title; nobody reading the title would think that question would be in it. I would hope you will find the explanation for your output in the “an output” link I posted.
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
oops. nevermind
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
P Malhotra wrote:Hi everyone

Why this is program is giving me this output([Falcon@e48e1b])


Because HashSet assumes your class follows the contract for equals. If you violate that, it's your fault, not HashSet's, when you get unexpected behavior.

hashcode of the Falcon's object is same but its still not calling the equals method.


It doesn't need to in this case. If you properly override equals, then it can evaluate new == existing as a shortcut before calling new.equals(existing). With a proper equals, the first implies the second.
 
Matthew Brown
Bartender
Posts: 4568
9
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, I'm not particularly surprised that it might not do what you expect when you try and do something strange like claim an object is not equal to itself. Anyway, it turns out that HashSet does not bother calling equals() if the objects are the same. Here's the relevant line from the source code (it's actually in HashMap, because HashSet uses one of those internally):

 
Mike Simmons
Ranch Hand
Posts: 3090
14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jeff Verdegan wrote:
Paul Clapham wrote:One of the rules for hashCode and equals is this:
If a.hashCode() == b.hashCode() is true then a.equals(b) must be true


Er... You wanna rethink that wording?

I'm a bit confused by the subsequent "oops. nevermind". Even if the comments above are not about the actual root problem in this case, they deserve to be fixed. The rule above is backwards - a correct version would be

If a.equals(b) is true then a.hashCode() == b.hashCode() must be true

However the more relevant rule here was the one also quoted by DrClap and several others: x.equals(x) must always return true.

 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mike Simmons wrote:
Jeff Verdegan wrote:
Paul Clapham wrote:One of the rules for hashCode and equals is this:
If a.hashCode() == b.hashCode() is true then a.equals(b) must be true


Er... You wanna rethink that wording?

I'm a bit confused by the subsequent "oops. nevermind".


I had written something else, then realized it was wrong. It didn't apply to suggesting a rewording--that still stands.

The rule above is backwards - a correct version would be

If a.equals(b) is true then a.hashCode() == b.hashCode() must be true



Correct. And I wasn't retracting my comment to that effect. :)

However the more relevant rule here was the one also quoted by DrClap and several others: x.equals(x) must always return true.



Exactly.
 
Consider Paul's rocket mass heater.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!