Different fields for equals and hashcode

2020-07-25 05:59发布

问题:

I agree with the statement from this post What issues should be considered when overriding equals and hashCode in Java?

Use the same set of fields that you use to compute equals() to compute hashCode().

But i've some doubts :

  • Is this absolutely necessary to have same fields ?
  • If yes, what if I don't use same field ?
  • Will it affect HashMap performance or HashMap Accuracy ?

回答1:

The fields don't have to be the same. The requirement is for two objects that are equal, they must have the same hash code. If they have the same hash code, they don't have to be equal. From the javadocs:

  • Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.
  • If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.
  • It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hash tables.

For example, you could return 1 as your hash code always, and you would obey the hash code contract, no matter what fields you used in your equals method.

Returning 1 all the time would improve the computation time of hashCode, but HashMap's performance would drop since it would have to resort to equals() more often.



回答2:

Is this absolutely necessary to have same fields ?

Yes, if you don't want any surprises.

If yes, what if I don't use same field ?

You might get different hashCode for objects that are equal, as per equals() method, which is a requirement for the equals and hashCode contract.

For example, suppose you've 3 fields - a, b, c. And you use a and b for equals() method, and all the 3 fields for hashCode() method. So, for 2 objects, if a and b are equals, and c is different, both will be equals with different hashcode.

Will it affect HashMap performance or HashMap Accuracy ?

It's not about performance, but yes your map will not behave as expected.



回答3:

Fields used in hashcode can be a subset of fields used in equals. It will still abide by this rule "Whenever a.equals(b), then a.hashCode() must be same as b.hashCode()"