• 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

hashCode() and equals() methods

 
Ranch Hand
Posts: 1164
Eclipse IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi

I have a few queries regarding hashCode() and equals() methods:

a) What exactly is a hashCode() of an object? What happens in the JVM when I invoke this method on an object? The JLS says that the hashCode() internally maps the memory address of an object to an integer. How is that implemented?

b) Secondly, why is it stated in the JLS that two equal objects must have equal hashCodes()? Could someone please quote an example?

 
Sheriff
Posts: 17644
300
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
We encourage everyone to do a SearchFirst(←click)

You can start helping yourself by searching for use of hash function.
 
Marshal
Posts: 79177
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Another place to look is Angelika Langer Java hash code equals. Beware: some of it is in German.
 
Mansukhdeep Thind
Ranch Hand
Posts: 1164
Eclipse IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:Another place to look is Angelika Langer Java hash code equals. Beware: some of it is in German.



This question is often asked in interviews that "When and why do we need to override equals() and hashCode() methods of Object class?" It was asked the last time and I could not answer it completely. I read the topic again. My understanding from what I have read in Kathy's SCJP for Java 6 book is as follows:

Collection classes using hashing algorithms like HashMap and Hashtable store objects against a hashCode() internally generated according to the objects actual location in the memory. Whenever we need to do a search for objects in any one of the collection classes using hashing (Hashtable, HashMap etc.) against a key, we have to override the equals() and hashCode() methods. This is done because:

a) Why override equals()? -> We have to check if the object in question is instance of the same class.(of the same type using instanceof operator) Secondly, we have to check at least one of its instance variables that describe its state against the object we want to be retrieved. If this returns true, we proceed to override the hashCode() method. This is done to ensure that the object we are searching for is of correct type and DOES ACTUALLY EXIST in the collection.

b) Why override hashCode()? --> Overriding equals() is only half the job done because we still have to home in on the correct memory area where the object might be located. We have to develop a simple hashing algorithm that will return the same integer value for 2 objects that passed the equals() test above. This can be done by multiplying that instance variable value by some prime number. This is done to ensure that we hit the right bucket while doing search. This is because the hashCodes() are basically integers that get generated according to object's location in the memory. So if we ensure that equal() objects have integrally equal hashCodes() , we increase our chances of finding the object in lesser time.

Please correct me if I am thinking on the wrong track here. Add something that I may have missed.
 
Rancher
Posts: 3742
16
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The hashCode method is used to check if two objects are NOT equal. If the hashCode method of one returns a different value to the hashCode method of the other then (as long as the hashCode method has been implemented correctly), you know that the two objects are NOT equal. There is now no need to call the equals method.
If the two objects return the same value from the hashCode method you then know that the objects MIGHT be equal. However you now have to call the equals method to actually find out if they are equal.

Therefore a well implemented hashCode method will, whenever possible, return different values for objects that are not equal as this will mean that there is no need to call the equals method. Because the hashCode value of an immutable object (and it's always best to use immutable objects in hashed collections) should never change, this improves the performance of any Collection that uses hashing because the value returned from the hashCode can be calculated when the object is created and doesn't need to be recalculated every time the method is called.

The equals method on the other hand has to compare each of its state fields with the corresponding field of the object it is being compared to every time that it is called. So reducing the number of calls to the equals method should improve performance.
 
Junilu Lacar
Sheriff
Posts: 17644
300
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
@OP:

That's not an explanation I would accept if I were interviewing you.

You override equals() when "equality" of objects means more than the default "equals()" which basically says if the other object is not this object, equals is false. There are other considerations, especially when factoring in inheritance.

You override hashcode() when you override equals() so that collections and other classes that use the hash of your object for efficient operation and depend on the contract between equals() and hashcode() to be honored, will work correctly with your object.
 
Mansukhdeep Thind
Ranch Hand
Posts: 1164
Eclipse IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Junilu Lacar wrote:@OP:

That's not an explanation I would accept if I were interviewing you.

You override equals() when "equality" of objects means more than the default "equals()" which basically says if the other object is not this object, equals is false. There are other considerations, especially when factoring in inheritance.

You override hashcode() when you override equals() so that collections and other classes that use the hash of your object for efficient operation and depend on the contract between equals() and hashcode() to be honored, will work correctly with your object.



OK Junilu. Now I am confused. Could you perhaps elaborate with a simple example ? May be provide a simple use case where you override equals() and hashCode(). Also explain why you did what you did. I need to get this into my head crystal clear.
 
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

Mansukhdeep Thind wrote:OK Junilu. Now I am confused. Could you perhaps elaborate with a simple example ? May be provide a simple use case where you override equals() and hashCode(). Also explain why you did what you did. I need to get this into my head crystal clear.


Well, as you saw from your other thread, two objects - say two Integer's - that are equal in value are not necessarily the same object (which is what '==' checks for), so it makes sense to implement some notion of "logically equal".

And for an Integer, that means that they contain the same numeric value.

Winston
 
Mansukhdeep Thind
Ranch Hand
Posts: 1164
Eclipse IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Junilu Lacar wrote:@OP:

That's not an explanation I would accept if I were interviewing you.

You override equals() when "equality" of objects means more than the default "equals()" which basically says if the other object is not this object, equals is false. There are other considerations, especially when factoring in inheritance.

You override hashcode() when you override equals() so that collections and other classes that use the hash of your object for efficient operation and depend on the contract between equals() and hashcode() to be honored, will work correctly with your object.



Hi Junilu
I read more about the topic here How to write equality method. This is what I could understand(Correct me if I am wrong):

We override hashCode() and equals() methods of Object class when we want to ensure that Hashing Collection classes(like Hashtable, HashMap, HashSet etc..) behave predictably and efficiently when we add/search for our stored objects in them. We need to correctly override equals in order to make sure that we are searching for the correct type of object and then compare the instance variable values of these. Now the collection class will know which object to search for.

Why override hashCode() when overriding equals? These hashing classes use "hash buckets" to store objects in , which are in a manner of speaking identified by hash codes which in turn are some transformation value of the actual memory addresses of objects. If we do not override hashCode() method of Object class, then surely the 2 objects in question will have different hash codes, although their equals() test returns true. This means that if we search for the object in the HashSet/HashMap, we may or may not find it i.e. contains() method will return unpredictable results. This is because the collection class is searching in the wrong bucket as the two equal() objects have different hash codes. Although the element is present in the collection, it may or may not be able to locate it. So, in order to ensure that hashing collection classes work smoothly , we have to honor the contract of equals() and hashCode().
 
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

Mansukhdeep Thind wrote:We override hashCode() and equals() methods of Object class when we want to ensure that Hashing Collection classes(like Hashtable, HashMap, HashSet etc..) behave predictably and efficiently when we add/search for our stored objects in them.


Correct for the hashCode method, but also see below for the equals method.

Mansukhdeep Thind wrote:We need to correctly override equals in order to make sure that we are searching for the correct type of object and then compare the instance variable values of these.


You override equals so that you can decide if two objects are equal. Forget about collections or anything else when thinking about the equals method. It is used for deciding if two objects are equal. That's all you need to know.

Mansukhdeep Thind wrote:Why override hashCode() when overriding equals?


Because it can increase performance when adding or retrieving objects to/from a hashed collection. See my previous post.

Mansukhdeep Thind wrote:which are in a manner of speaking identified by hash codes which in turn are some transformation value of the actual memory addresses of objects.


In the implementation of hashCode in the Object class, possibly but not necessarily. In any overridden hashCode method, it's highly unlikely the hash code will have any relation to a memory address, because two equal objects will not have the same memory address.

Mansukhdeep Thind wrote:If we do not override hashCode() method of Object class, then surely the 2 objects in question will have different hash codes, although their equals() test returns true.


Exactly. That's why you have to override the hashCode method.
 
Mansukhdeep Thind
Ranch Hand
Posts: 1164
Eclipse IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you Joanne. Finally I nailed it. High5!!
 
Campbell Ritchie
Marshal
Posts: 79177
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Disagree about those answers. The correct answer is, in my opinion,

Always override equals and hashCode, except for a few special cases.

Then you can say what those special cases are.
 
Mansukhdeep Thind
Ranch Hand
Posts: 1164
Eclipse IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:Disagree about those answers. The correct answer is, in my opinion,

Always override equals and hashCode, except for a few special cases.

Then you can say what those special cases are.



Disagree with whose answers? Joanne's or mine ?
 
Campbell Ritchie
Marshal
Posts: 79177
377
  • Likes 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Everybody’s.
You should not go round thinking, “do I have to override equals() and hashCode() here?”. You think you must override them unless your class falls in one of the special cases where they are not required.
 
Mansukhdeep Thind
Ranch Hand
Posts: 1164
Eclipse IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:Everybody’s.
You should not go round thinking, “do I have to override equals() and hashCode() here?”. You think you must override them unless your class falls in one of the special cases where they are not required.



Thanks for correcting my thought process Ritchie. It is important that we ask the right questions to get the right answers. This thread simply reinforces that fact. May I ask under what special circumstances will I NOT do this?
 
Junilu Lacar
Sheriff
Posts: 17644
300
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:Everybody’s.
You should not go round thinking, “do I have to override equals() and hashCode() here?”. You think you must override them unless your class falls in one of the special cases where they are not required.


That doesn't mesh with what I have seen in many years of development. In my experience, if I had one hundred domain classes in a system, I'd only have a need to override equals() and hashCode() for a very small fraction of those classes. I don't have to go wondering about it all the time either because a failing test will tell me when equals() and hashCode() need to be overidden. The need to override equals() and hashCode() is more an exception rather than a rule, at least on the systems that I've worked on.

Moreso with classes like controllers, view-models, facades, DAOs, builders, factories, bridges, adapters, decorators, etc. There are so many kinds of classes that you don't really care about their "logical equality". Why spend the time and effort writing equals() and hasCode() for these when you're never going to need them?

Pragmatically speaking, you have to strike a balance between the desire to be conceptually "correct" and having a class that's "good enough" for what it has to do. If logical equality never comes into play for a class, I wouldn't spend any time writing and testing custom equals() and hashCode() implementations. YMMV.
 
Campbell Ritchie
Marshal
Posts: 79177
377
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yes, I think I have gone too far the other way.

DAOs and bridges obviously don’t need overridden equals methods.
Nor do classes designed to change their state very quickly.
Nor do classes intended as short-lived throwaway objects, because they are never around long enough to need equality testing.
Nor do utility classes, because you never instantiate them and can’t call equals.
Nor do classes which are singletons (which to all intents and purposes means enum elements), because the java.lang.Object version does exactly what you want.
Nor do things like Class and Thread because every instance is implicitly different from every other instance.
Most classes shown on these fora do not have overridden equals methods because they are short-lived classes used for training.
 
Campbell Ritchie
Marshal
Posts: 79177
377
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Classes which don’t encapsulate any values don’t need equals methods, because they have nothing to compare.
 
Mansukhdeep Thind
Ranch Hand
Posts: 1164
Eclipse IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:Classes which don’t encapsulate any values don’t need equals methods, because they have nothing to compare.



Thanks a lot Ritchie. I don't know how many times I will be saying this in future..
 
Mansukhdeep Thind
Ranch Hand
Posts: 1164
Eclipse IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:Yes, I think I have gone too far the other way.

DAOs and bridges obviously don’t need overridden equals methods.
Nor do classes designed to change their state very quickly.
Nor do classes intended as short-lived throwaway objects, because they are never around long enough to need equality testing.
Nor do utility classes, because you never instantiate them and can’t call equals.
Nor do classes which are singletons (which to all intents and purposes means enum elements), because the java.lang.Object version does exactly what you want.
Nor do things like Class and Thread because every instance is implicitly different from every other instance.
Most classes shown on these fora do not have overridden equals methods because they are short-lived classes used for training.



What are DAOs and bridges?
 
Junilu Lacar
Sheriff
Posts: 17644
300
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Mansukhdeep Thind wrote:
What are DAOs and bridges?



Please do a SearchFirst (←click on the link) -- these are well-known design patterns
 
Winston Gutkowski
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

Junilu Lacar wrote:Moreso with classes like controllers, view-models, facades, DAOs, builders, factories, bridges, adapters, decorators, etc. There are so many kinds of classes that you don't really care about their "logical equality". Why spend the time and effort writing equals() and hasCode() for these when you're never going to need them?


Hmmm. I agree with most of that list; but surely for adapters, decorators and views you're likely to at least want forwarders for them?

I'd also say that there is a case for providing an equals() method, but no hashCode() (or perhaps one that just throws an Exception), for mutable objects, providing you document it well.

Winston
 
Campbell Ritchie
Marshal
Posts: 79177
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Mansukhdeep Thind wrote: . . . What are DAOs and bridges?

I think data access objects and don’t know.
 
First, you drop a couch from the plane, THEN you surf it. Here, take this tiny ad with you:
a bit of art, as a gift, that will fit in a stocking
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic