File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Beginning Java and the fly likes hashCode() and equals() methods Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "hashCode() and equals() methods " Watch "hashCode() and equals() methods " New topic
Author

hashCode() and equals() methods

Mansukhdeep Thind
Ranch Hand

Joined: Jul 27, 2010
Posts: 1157

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?


~ Mansukh
Junilu Lacar
Bartender

Joined: Feb 26, 2001
Posts: 4456
    
    6

We encourage everyone to do a SearchFirst(←click)

You can start helping yourself by searching for use of hash function.


Junilu - [How to Ask Questions] [How to Answer Questions]
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38353
    
  23
Another place to look is Angelika Langer Java hash code equals. Beware: some of it is in German.
Mansukhdeep Thind
Ranch Hand

Joined: Jul 27, 2010
Posts: 1157

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.
Joanne Neal
Rancher

Joined: Aug 05, 2005
Posts: 3446
    
  12
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.

Joanne
Junilu Lacar
Bartender

Joined: Feb 26, 2001
Posts: 4456
    
    6

@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

Joined: Jul 27, 2010
Posts: 1157

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.
Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 7643
    
  19

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

Isn't it funny how there's always time and money enough to do it WRONG?
Articles by Winston can be found here
Mansukhdeep Thind
Ranch Hand

Joined: Jul 27, 2010
Posts: 1157

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

Joined: Aug 05, 2005
Posts: 3446
    
  12
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

Joined: Jul 27, 2010
Posts: 1157

Thank you Joanne. Finally I nailed it. High5!!
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38353
    
  23
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

Joined: Jul 27, 2010
Posts: 1157

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
Sheriff

Joined: Oct 13, 2005
Posts: 38353
    
  23
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

Joined: Jul 27, 2010
Posts: 1157

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
Bartender

Joined: Feb 26, 2001
Posts: 4456
    
    6

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
Sheriff

Joined: Oct 13, 2005
Posts: 38353
    
  23
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
Sheriff

Joined: Oct 13, 2005
Posts: 38353
    
  23
Classes which don’t encapsulate any values don’t need equals methods, because they have nothing to compare.
Mansukhdeep Thind
Ranch Hand

Joined: Jul 27, 2010
Posts: 1157

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

Joined: Jul 27, 2010
Posts: 1157

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
Bartender

Joined: Feb 26, 2001
Posts: 4456
    
    6

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

Joined: Mar 17, 2011
Posts: 7643
    
  19

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
Sheriff

Joined: Oct 13, 2005
Posts: 38353
    
  23
Mansukhdeep Thind wrote: . . . What are DAOs and bridges?
I think data access objects and don’t know.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: hashCode() and equals() methods