开发者

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 开发者_JAVA技巧balances? Is it that I misunderstood the concept somewhere? Can someone clarify this for me?


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.


You have to check at least all the fields used by .hashCode() so objects which are equal do have the same hash. But you can check more fields in equals, its totally fine to have different objects with the same hash. It seems your doing SCJP 1.6? This topic is well covered in the SCJP 1.6 book from Katherine Sierra and Bert Bates.

Note: thats why its legit to implement a useful .equals() while returning a constant value from .hashCode()


It's all about fulfilling the contract (as far as this question is concerned). Different implementation (of hasCode and equal) has different limitations and its own advantages - so its for developer to check that.

but then they get different hashCode because they have a different balance?
Exactly! But that's why you should choose option C. The question wants to test your grasp on fulfilling the contract concept and not which hascode will be better for the scenario.

More clarification:
The thing you need to check always is : Your hashCode() implementation should use the same instance variables as used in equals() method.

Here these instance variables are : code.length() and bal used in hashCode() and hence you are limited to use these same variables in equals() as well. (Unless you can edit the hashCode() implementation and add rate to it)


  1. hashCode() method is used to get a unique integer for given object. This integer is used to determined the bucket location, when this object need to be stored in some HashTable like HashMap data structure. But default, Object's hashCode() method returns an integer to represent memory address where object is stored.

  2. equals() method, as name suggest, is used to simply verify the equality of two objects. Default implementation just simply check the object references of two object to verify their equality.

equal objects must have equal hash codes.

equals() must define an equality relation. if the objects are not modified, then it must keep returning the same value. o.equals(null) must always return false.

hashCode() must also be consistent, if the object is not modified in terms of equals(), it must keep returning the same value.

The relation between the two method is:

whenever a.equals(b) then a.hashCode() must be same as b.hashCode().

refer to: https://howtodoinjava.com/interview-questions/core-java-interview-questions-series-part-1/


In general, you should always override one if you override the other in a class. If you don't, you might find yourself getting into trouble when that class is used in hashmaps/hashtables, etc.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜