permaculture playing cards*
The moose likes Java in General and the fly likes Overriding hashCode() and equals() Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Java in General
Bookmark "Overriding hashCode() and equals()" Watch "Overriding hashCode() and equals()" New topic
Author

Overriding hashCode() and equals()

Sudhanshu Mishra
Ranch Hand

Joined: May 28, 2011
Posts: 217

Hi all,
I have a doubt regarding hashCode() and equals() override.
Why is it important that we override hashcode() if we override equals()?I mean,hashCode() refers to memory address of the object,and two objects can be 'equal' even if they are not at the same memory location?
Please be patient with my ignorance and help me.

Thanks...
Lanny Gilbert
Ranch Hand

Joined: Jun 11, 2002
Posts: 103
If you override the equals(), you MUST also override hashCode(). Otherwise a violation of the general contract for Object.hashCode will occur, which can have unexpected repercussions when your class is in conjunction with all hash-based collections.

You can find more excruciating detail in the Java Language Specification, but suffice it to say that if you override equals(), you most override hashCode() because the
language designers say so
marlajee Borstone
Ranch Hand

Joined: Jun 26, 2008
Posts: 35
But I am not sure why we need at all to override the equals() and hascode() methods in any class; because if we look into this example:-
Say we have a class which has a String variable as isbn which needs to be set by passing through constructor.
ie.

This code segment will display objects are equal even though firstBook and secondBook reference two distinct objects. They are considered equal because the objects compared contain the same value.

By overriding the equals() and hascode() method we do nothing new rather than generating a hashcode which uses all the variables values used in that object. So that if that object is compared with any other object, the hashcode() will be check and if it is found as same then they are decided to be equal.

So, why do we need to bother to override this equals() and hascode(), why just follow the process as shown above for firstBook and secondBook ?

Please help to get the clear reasoning regarding this above example in context with overriding equals() and hascode().

I will appreciate your input...

regards,
Dhannsumal !!
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19682
    
  19

marlajee Borstone wrote:This code segment will display objects are equal even though firstBook and secondBook reference two distinct objects. They are considered equal because the objects compared contain the same value.

That depends on the implementation of class Book. With the following implementation they are not equal:
You have to override equals (and therefore also hashCode) to specify what equality means. In your example you assumed that Book equality means ISBN equality, but you do have to implement that first.


SCJP 1.4 - SCJP 6 - SCWCD 5 - OCEEJBD 6
How To Ask Questions How To Answer Questions
Aditya Jha
Ranch Hand

Joined: Aug 25, 2003
Posts: 227

@Sudhanshu

There are very good reasons behind overriding equals() and hashCode() in a custom class.

Try to search some reference on how HashMap and HashSet work with custom objects. This will give you an insight on exactly why (and how) one needs to implement equals() and hashCode() in a custom class, in order to get desired results with Hash-based collection classes. It's always good to know the reasons behind the rules of the language, as opposed to take them on face value. You tend to appreciate them more if you know why those rules were put up in the first place. (For example, why can't an overriding method throw a checked exception not thrown by overriding method?)

@marlajee
As Rob explained, the Book class may contain properties ISBN, Title, Authors etc. Which property should be used for equals() comparison still needs to be implemented within the class, else the 2 objects will not be deemed equal in your example.
Will Myers
Ranch Hand

Joined: Aug 05, 2009
Posts: 325

have a look at the way hascode has been implemented in Object, the default is to convert the memory address of the object into an int and use that. This means that if you override the equals method only and not hascode, calling hashcode on the 2 objects will return different numbers. If you then put these into a hashed collection you won't be able to retrieve them...
Santosh Kumar Nayak
Ranch Hand

Joined: Aug 02, 2011
Posts: 93
I have an Employee class and I am putting objects E1,E2,E3 in HashMap.

In case I have not overridden the hashode method in my Employee class hence it shall be using the hashcode of the Object class.

In that scenario when we are using the hashcode method of the Object class then what is the int value returned from the Hashcode method ?
Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 7703
    
  20

Santosh Kumar Nayak wrote:In that scenario when we are using the hashcode method of the Object class then what is the int value returned from the Hashcode method ?

It's not specified; but the docs say that it will often be a "mangled" version of its memory address or reference.

Simply put: it's not important. The only thing that you need to know is that it will be consistent (and ONLY consistent) with Object.equals(), so if you override equals(), but not hashCode(), you will almost certainly end up with them NOT being consistent with each other.

HIH

Winston

Isn't it funny how there's always time and money enough to do it WRONG?
Articles by Winston can be found here
Joanne Neal
Rancher

Joined: Aug 05, 2005
Posts: 3496
    
  13
Santosh Kumar Nayak wrote:In that scenario when we are using the hashcode method of the Object class then what is the int value returned from the Hashcode method ?

It's impossible to tell and there's a good chance it will be different each time you run your program. The only thing you can say for certain is (from the javadoc for Object)
As much as is reasonably practical, the hashCode method defined by class Object does return distinct integers for distinct objects.


Joanne
Santosh Kumar Nayak
Ranch Hand

Joined: Aug 02, 2011
Posts: 93
So you mean different hashcode values for different objects like E1,E2 and E3.

Then in that scenario the complexity for retrieving value will be less as compared to complexity for retrieving value if the hashcode was same for all the objects ?



Joanne Neal
Rancher

Joined: Aug 05, 2005
Posts: 3496
    
  13
Santosh Kumar Nayak wrote:Then in that scenario the complexity for retrieving value will be less as compared to complexity for retrieving value if the hashcode was same for all the objects ?

I have no idea what you mean by that.
What value are you talking about and where are you retrieving it from ?
Rico Felix
Ranch Hand

Joined: Mar 08, 2014
Posts: 253
    
    3

You need to override both the equals(Object) and hashCode() methods only when you need to store those objects in data structures that uses hashing algorithms for storing data (key-value pairs). The reason for this is so that the hashing algorithm can successfully store and retrieve the location of the object in the structure using the hash-code then uses the equals methods to determine if a match has been found.

To elaborate on this lets use some illustration:

The default hashCode method located in the Object class which all objects in Java inherits returns a unique arbitrary value for every object created. So if we create two custom classes of type Circle we would get something like this for the instances hash-codes:



So from this information it is understood that for data structures that use hash-code values for storing data you will run into trouble when putting values in and getting them back out if we don't override both methods. If you put a Circle object as a key with a radius of 7 in such a structure and that circle object has a hash-code value of 23afde it might be placed at location 3 in the data structure which will be used to locate its associated value. Now if say a few lines later in your code or even worse if your application uses serialization and you close your application to reopen it and retrieve the object stored in the structure it will be impossible. This is because the revived or newly created object will have a new hash-code such as 23aee1 and when you pass that it into the structure to find its associated value the structure will not be able to find the location since 23afde referring to location 3 and 23aee1 probably referring to location 77 are two very distinct address locations even though both circle objects have a radius of 7. To overcome this we override the equals and hashCode methods as follows:



Now that we override both the equals and hashCode methods every object that is equal will have the same hashCode value. Going back to the previous scenario with this new implementation the location of every circle object with a radius of 7 will have the same location (7 * 7 + 2) = 59 pointing at location 3. The structure will now be able to find the value for key by supplying a circle object with a radius of 7. And this is the reason to override the equals and hashCode methods together.
Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 7703
    
  20

Rico Felix wrote:You need to override both the equals(Object) and hashCode() methods only when you need to store those objects in data structures that uses hashing algorithms for storing data (key-value pairs).

What you say is true; however, when you write a class, you rarely know whether anyone who uses it will want to store it in such a structure, so the usual rule is to assume that they will.

And, given that premise:
If you override equals(), you must override hashCode().

It's also worth remembering that even if you do override equals()/hashCode(), you can still use an IdentityHashMap to store objects by identity.

Also: <nitpick> it's not restricted to data structures that store key-value pairs. HashSet, for example, doesn't. </nitpick>

However, I do like your illustration. Good old Circle.

Winston
Rico Felix
Ranch Hand

Joined: Mar 08, 2014
Posts: 253
    
    3

I see... Thank you for the correction...
 
 
subject: Overriding hashCode() and equals()