javaequalshashcodescjp

equals and hashCode


I am running into a question about equals and hashCode contracts: here it is

Given:

class SortOf { 
  String name; 
  int bal; 
  String code; 
  short rate; 
  public int hashCode() { 
    return (code.length() * bal); 
  } 
  public boolean equals(Object o) { 
    // insert code here 
  } 
} 

Which of the following will fulfill the equals() and hashCode() contracts for this class? (Choose all that apply.)

Correct Answer C:

return ((SortOf)o).code.length() * ((SortOf)o).bal  ==  this.code.length() * 
    this.bal; 

D:

return ((SortOf)o).code.length() * ((SortOf)o).bal * ((SortOf)o).rate ==
    this.code.length() * this.bal * this.rate; 

I have a question about the last choice D, say if the two objects

A: code.length=10, bal=10, rate = 100

B: code.length=10, bal=100, rate = 10

Then using the equals() method in D, we get A.equals(B) evaluating to true right? But then they get a different hashCode because they have different balances? Is it that I misunderstood the concept somewhere? Can someone clarify this for me?


Solution

  • You're right - D would be inappropriate because of this.

    More generally, hashCode and equals should basically take the same fields into account, in the same way. This is a very strange equals implementation to start with, of course - you should normally be checking for equality between each of the fields involved. In a few cases fields may be inter-related in a way which would allow for multiplication etc, but I wouldn't expect that to involve a string length...

    One important point which often confuses people is that it is valid for unequal objects to have the same hash code; it's the case you highlighted (equal objects having different hash codes) which is unacceptable.