• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Overriding hashCode() and equals()

 
Ranch Hand
Posts: 238
1
Eclipse IDE Fedora Java
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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...
 
Ranch Hand
Posts: 162
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
 
Ranch Hand
Posts: 35
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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 !!
 
Sheriff
Posts: 22781
131
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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.
 
Ranch Hand
Posts: 227
Eclipse IDE Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
@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.
 
Ranch Hand
Posts: 462
Scala jQuery Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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...
 
Ranch Hand
Posts: 230
IntelliJ IDE Eclipse IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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 ?
 
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
 
Rancher
Posts: 3742
16
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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.

 
Santosh Kumar Nayak
Ranch Hand
Posts: 230
IntelliJ IDE Eclipse IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 3742
16
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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 ?
 
Ranch Hand
Posts: 411
5
IntelliJ IDE Java Linux
  • Likes 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Likes 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 411
5
IntelliJ IDE Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I see... Thank you for the correction...
 
He loves you so much! And I'm baking the cake! I'm going to put this tiny ad in the cake:
a bit of art, as a gift, the permaculture playing cards
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic