Why does overriding equals require overriding hashCode
In alibaba development manual – Huashan edition there is a mandatory provision:
[Mandatory] Handle hashCode and equals according to the following rules:
1) Whenever you override equals, you must override hashCode.
2) The value of a Set must be duplicated by hashCode and equals
Let me write these two methods.
3) If a custom object is used as a Map key, then hashCode and equals must be overridden.
Note: String overrides the hashCode and equals methods, so we can happily use String objects as keys.
We can get the following from the comment above the hashCode method in the Object class:
- Calling the hashCode method on the same object repeatedly returns the same result. (Assuming the object has not been modified)
- If two objects are equal using the equals method, then the two objects return the same value when called to hashCode
- The hashCode values of two objects are equal; they are not necessarily equal.
From this, we can draw the conclusion that:
- If two objects have the same equals result, the hashCode value must be equal.
- If the hashCode values of two objects are not equal, then the two objects are not identical either.
Equals equals equals equals equals equals equals equals equals equals equals equals equals equals equals equals equals
- It is reflexive: for any non-null reference value x, x.equals(x) should return true.
- It is symmetric: for any non-null reference values x and y, x.quals (y) should return true if and only if y.quals (x) returns true.
- It is transitive: for any non-null reference values x, y, and z, if x.quals (y) returns true and y.quals (z) returns true, then x.quals (z) should return true.
- It is consistent: multiple calls to x.equals(y) always return true or always return false for any non-null reference values x and y, provided that the information used in the equals comparison of the objects has not been modified. For any non-null reference value x, x. beers (null) should return false.
One particular note in the comments is that whenever this method is overridden, it is usually necessary to override the hashCode method to maintain the general convention of the hashCode method that equal objects must have equal hash codes.
It should also be clear that hashCode and equals are used together. So how do you understand that overwriting equals requires overwriting hashCode?
We can see from the Object class that equals compares directly with ==. So return true if two reference objects refer to the same instance allocated memory in the heap, and false otherwise.
However, the equals method of the Object class was not sufficient in our real development. When two objects reference different instances of the heap, it will consider them to be unequal. But in real development, we consider two objects to be equal based on whether the properties of their instances are equal.
Here’s an example:
A a1 = new A("123");
A a2 = new A("123");
a1.equals(a2);
Copy the code
The above code, if not overridden, would result in false. In the heap, there would be two different instances, but in real development, we want to compare the property contents to be equal. In this case, a1 and A2 property contents are the same, so a1.equals(a2) should return true. This is also quite common, for example with the common String class, which overrides equals to return true if the contents are equal.
So, back to the original problem, we know from the official comment of the hashCode method that if two objects return true after equals, then hashCode must be equal. So, when overriding equals, we must override hashCode to ensure that the hashCode values are equal, otherwise we violate the original principle.
Anyway, whenever you override equals, you need to override hashCode. We see the String class in Java, which is used a lot in Java collections, such as the HashMap/Set collection we usually use, are often used as a String type as a key.
I. If strings do not override equals (or inherit the equals method from Object), then identical strings may be treated as two different keys.
If String overrides equals, hashCode is not overridden. The same key will appear in different positions, because the hash function is often used in the set to calculate the position of the key. If hashCode is not overwritten, the same key will have different hashCode values, resulting in different positions.