Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HashCode isn't called by Equals explanation

The doc says: 'hashCode isn't called by equals and vice-versa'.

But, reading other people comments, they actually are.

Let me put this through some easy example. I have a Employee class. Equal method returns true if both name and id are same. While HashCode returns id.

So what happens now? I make a Set of employees and I add two employees. One has id 1 and name "a", other has id 1 and name "b". What happens? Both of them are added.

Obviously equals has been called after JAVA has seen they are in same bucket. Doesn't that violate documents from my first sentence? Am I missing something?

Thanks

like image 642
Stefan Jankovic Avatar asked Jan 18 '26 21:01

Stefan Jankovic


2 Answers

Yes, you are missing something:

Your statement is that the hashCode method does not call the equals method and visa versa, and generally, this is so.

This does not mean that other code that uses one of these methods doesn't call the other, and in fact often this is the case, such as a HashMap that uses the hashCode to initially assign an object to a "box" and then uses the equals method to further distinguish between different objects. But this still does not violate my first statement.

like image 165
Hovercraft Full Of Eels Avatar answered Jan 20 '26 11:01

Hovercraft Full Of Eels


The doc says: 'hashCode isn't called by equals and vice versa'.

I am not sure which "doc" you are referring to. (I googled for the statement that you quoted and could not find it.) Hence it is not clear what it is actually referring to.

However, if this refers to the specific implementations of hashCode and equals in java.lang.Object, then it is certainly correct.

  • Object::equals(String) simply uses == to compare the objects.
  • Object::hashCode() calls System.identityHashCode(Object) which doesn't compare the object with anything.

But reading other people comments, they actually are.

If you don't cite the comments, we can't explain them.


Let me put this through some easy example. I have Employee class. The equals(Object) method returns true if both name and id are same. While hashCode returns the id.

That is a legitimate implementation, assuming that your equals has the right signature, and takes care of the cases where the other object null or where it is not an Employee.

So what happens now? I make a Set of employees and I add two employees. One has id 1 and name "a", other has id 1 and name "b". What happens? Both of them are added.

That is correct, assuming that you are using a HashSet. (Set is an interface.)

(It is a mistake for two Employee objects to have the same id, but that is peripheral to your question.)

Obviously equals has been called after Java has seen they are in same bucket.

That is correct.

Doesn't that violate documents from my first sentence?

No.

The statement you quoted says that hashCode doesn't call equals. But that's not what has happened here. What has happened here is:

  1. You have called HashSet::add(E) to add an Employee to the set.
  2. HashSet::add(E) has called Employee::hashCode() and used it to find the bucket1.
  3. HashSet::add(E) has called Employee::equals(Object) to compare the Employee being added against other Employee objects in the bucket2.

Note that it is NOT the hashCode method that is calling equals. So there is no contradiction.


1, 2 - These a drastically simplifying what happens. Look at the source code for the full details.

like image 36
Stephen C Avatar answered Jan 20 '26 10:01

Stephen C



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!