Bookmark Topic Watch Topic
  • New Topic

override equal and hashcode method  RSS feed

 
abalfazl hossein
Ranch Hand
Posts: 635
  • Mark post as helpful
  • send pies
  • Report post to moderator
I read this tutorial about overriding equal and hashcode method.

http://javapapers.com/core-java/hashcode-and-equals-methods-override/

I understand how to override equal method, by overriding it, We can custom our compare

I also understand How to override hashcode, To make custom hash.

But still I can not understand why we do it? why if equal method override, we must override hashcode method too?If we don't what is the problem?

To honor the above contract we should always override hashCode() method whenever we override equals() method. If not, what will happen? If we use hashtables in our application, it will not behave as expected. As the hashCode is used in determining the equality of values stored, it will not return the right corresponding value for a key.


Is it the right reason in order to override:

Because when we customize equal method so it focus on special variables,We must change the hash code too in order to match with it, so hashcode also focus on those special variable.

Right?
 
Ulf Dittmer
Rancher
Posts: 42972
73
  • Mark post as helpful
  • send pies
  • Report post to moderator
These two quotes explain why:
I also understand How to override hashcode, To make custom hash.


As the hashCode is used in determining the equality of values stored, it will not return the right corresponding value for a key.


You need to ensure that distinct objects have distinct hash codes, otherwise hashing is not guaranteed to work.
 
abalfazl hossein
Ranch Hand
Posts: 635
  • Mark post as helpful
  • send pies
  • Report post to moderator
Is it the right reason in order to override:

Because when we customize equal method so it focus on special variables,We must change the hash code too in order to match with it, so hashcode also focus on those special variable.

Right?

For example if the class has 3 variable and we know equal two objects if x1 and y1 be equal to x2 and y2,and wedon't care about z.

So we must override hashcode so it creates the code according to x and y, not z.
 
Ulf Dittmer
Rancher
Posts: 42972
73
  • Mark post as helpful
  • send pies
  • Report post to moderator
The important thing is that hashCode fulfills the contract spelled out in its javadocs; the implementation details are not so important. But yes, in this case it would probably depend on x and y, but not z.
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Report post to moderator
abalfazl hossein wrote:Is it the right reason in order to override:
Because when we customize equal method so it focus on special variables,We must change the hash code too in order to match with it, so hashcode also focus on those special variable.

Yes and no. The reason you need to override it is that Object's hashCode() method is designed to work with ITS equals() method, so it will almost always return a different hashcode for distinct (ie, "!=", as opposed to "not 'equal'") objects.

To my mind, the Java designers made a mistake there. I would have had it return 17 (a constant, and a prime number), and adjusted the documentation accordingly. Then it would work in "hashed" collections with ANY implementation of equals() - just not very well.

Winston
 
Tim Holloway
Saloon Keeper
Posts: 18799
74
Android Eclipse IDE Linux
  • Likes 1
  • Mark post as helpful
  • send pies
  • Report post to moderator
Ulf Dittmer wrote:
You need to ensure that distinct objects have distinct hash codes, otherwise hashing is not guaranteed to work.


Uh, no. That's the difference between a unique code and a generic hash code. Hashing is a process whereby you attempt to reduce an object (or object reference) to a small, easily-handled value. It's like a UUID/GUID except that it's usually much smaller (in Java, it's the size of an int), and doesn't attempt to truly be truly (globally/universally) unique (the "GU" in GUID, "UU" in UUID).

This distinction is important because when you implement a hash table, a non-unique hash code has the potential to generate hash collisions. That is, 2 or more objects have the same hash code. Hash tables solve this problem by attaching an overflow list to the hash slot in question.

A "perfect hash" is one where, for the set of expected hash values, each associated object has a unique value. That's important in a hash table because it means you don't need an overflow list. The other side of the equation is that you have a minimum number of slots (ideally 0) that won't ever be filled. What defines a perfect hash isn't the possible values of the data, it's the expected actual working values of the data. So, while having an int return its value is a perfect hash for a table of 4.4 billlion slots, a more modest table that's only 17 slots wide would require an algorithm that reduced the hash codes to one of 17 values. What that algorithm is should be varies (as I said, based) on the expected data. If, for example, the possible/expected values to be hash-computed are the even-numbered integers between 34 and 68, the algorithm for a perfect hash would be n/2 modulo 17.

Hash tables are generally defined as being a prime number of slots wide, as it makes it easier for single algorithms not to dump everything in relatively few slots due to common factoring.

In Java, hashCode and equals have special importance for such things as database Object Model entities. These entities usually define their hash values based solely on the key fields, not on all fields in the record. So if you have 2 objects of type Employee and Employee has a key field named "empNum", then the hashCode would use that property to calculate the hashCode and the equals algorithm is basically just comparing 2 objects to see if they are both Employee objects and that they have the same empNum value. They may have 2 different salary property values, but for the needs of the Object Model system, they are considered to be the same record (just updated). The equals() method thus ensures that the proper database record is targeted. The hashCode() method typically makes it easier for the Object Model manager (such as EJB or Hibernate) to find cached objects.
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Report post to moderator
Tim Holloway wrote:It's like a UUID/GUID except that it's usually much smaller (in Java, it's the size of an int), and doesn't attempt to truly be truly (globally/universally) unique (the "GU" in GUID, "UU" in UUID).

Which, I hate to say, makes it almost totally different.

I like to think of a hashcode as the "antithesis" of an ID: It tells you when objects are different; NOT when they're "equal" - the integral (or functional) extension of an "XOR" if you like. And it only does that if they're good (which is what your excellent post is all about).

Sheesh. Who would've thought that something as "simple" as equals() (and hashCode()) could be so darn complicated?

Winston
 
abalfazl hossein
Ranch Hand
Posts: 635
  • Mark post as helpful
  • send pies
  • Report post to moderator
It is NOT required that if two objects are unequal according to the
equals(java.lang.Object) method, then calling the hashCode() method
on each of the two objects must produce distinct integer results. However,
the programmer should be aware that producing distinct integer results for
unequal objects may improve the performance of hashtables.

JAVA SCJP book

so it will almost always return a different hashcode for distinct (ie, "!=", as opposed to "not 'equal'") objects.


It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results.


http://www.javaranch.com/journal/200407/ScjpTipLine-hashCodesUncovered.html


I think that it is better to say:

if two object are equal according equal method,Then calling hashcode must return same integer result.Right?
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Likes 2
  • Mark post as helpful
  • send pies
  • Report post to moderator
abalfazl hossein wrote:I think that it is better to say:
if two object are equal according equal method,Then calling hashcode must return same integer result.Right?

Right. And it's actually stated that way in the rules.

What most beginners fail to grasp is that this makes hashCode() an indicator of inequality, not equality.

So the way I prefer to state it is:
If hashcodes are different, then you know that the two objects are different.

Or, more formally:
If a.hashCode() is NOT equal to b.hashCode(), then a.equals(b) MUST return false.

Unfortunately, the way it's stated in the rules doesn't make this very clear.

HIH

Winston
 
Tim Holloway
Saloon Keeper
Posts: 18799
74
Android Eclipse IDE Linux
  • Likes 1
  • Mark post as helpful
  • send pies
  • Report post to moderator
Winston Gutkowski wrote:

I like to think of a hashcode as the "antithesis" of an ID: It tells you when objects are different;


I like that.

Winston Gutkowski wrote:
Sheesh. Who would've thought that something as "simple" as equals() (and hashCode()) could be so darn complicated?

Winston


In computers, complicated things are often easier than "easy" things. It's why I fall down on the floor and foam at the mouth when people tell me "All You Have To Do Is..."
 
Campbell Ritchie
Marshal
Posts: 56570
172
  • Mark post as helpful
  • send pies
  • Report post to moderator
Foaming at the mouth only works if you bit them as well
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Report post to moderator
Tim Holloway wrote:In computers, complicated things are often easier than "easy" things. It's why I fall down on the floor and foam at the mouth when people tell me "All You Have To Do Is..."

"...create a webpage with our data".

We used to call 'em "fag packet specs", which probably doesn't translate well, but hopefully you get the drift.

Winston
 
Anindya Roy
Ranch Hand
Posts: 76
 
Campbell Ritchie
Marshal
Posts: 56570
172
  • Mark post as helpful
  • send pies
  • Report post to moderator
That is a poor tutorial because it does not discuss any of the likely problems with equals(), only one potential problem with hashCode(). Search this forum and Java in General for equals method and you will find lots of discussions. You will also find links to better references, for example in our FAQ.
 
Campbell Ritchie
Marshal
Posts: 56570
172
  • Mark post as helpful
  • send pies
  • Report post to moderator
To avoid duplicate discussions, please continue the discussion here.
 
    Bookmark Topic Watch Topic
  • New Topic
Boost this thread!