programming forums Java Java JSRs Mobile Certification Databases Caching Books Engineering Languages Frameworks Products This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
Sheriffs:
Saloon Keepers:
Bartenders:

# equals and hashCode

Sebanti Sanyal
Ranch Hand
Posts: 58

Which of the following will fulfill the equals() and hashCode() contracts for this class? (Choose all that apply.)
A. return ((SortOf)o).bal==this.bal;
B. return ((SortOf)o).code.length()==this.code.length();
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;

EXPLANATION:
C and D are correct. The equals() algorithm must be at least as precise in defining what "meaningfully equivalent" means as the hashCode() method is.
A and B are incorrect because these equals() implementations would allow instances to be equal that hashCode() would not see as equal.

Ref: question from K&B MasterExam CD

I feel only C is correct. I tested with D using the following main() function.

Output is: true false

Am I missing something here?

Stephan van Hulst
Saloon Keeper
Posts: 7737
142
None of the answers are correct. The equals() contract explicitly states that x.equals(null) should return false. None of the implementations fulfill this requirement.

Larsen Raja
Ranch Hand
Posts: 58

As per the contract, once two objects satisfy equals criteria obviously their hashcodes should be equal. So considering the example stated,
Obj1. hashcode = code.length * lab.
ex: Obj1.code.length = 7 obj1.bal = 8
Obj2.code.length = 8 obj2.bal = 7;
for both the above cases, hashCode = 56.

Consider choice C:

((SortOf)o).code.length()*((SortOf)o).bal==this.code.length()*this.bal; => 7 * 8 == 8 * 7 returns true. Hence hashcode and equals contract gets satisfied at this point.

Consider choice D:

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

By simple mathematics,

for equal rates, the above expression can be evaluated to nothing but choice C.

C works out normally. But D works out only when rates are equal for objects.

Correct if am worng.

dennis deems
Ranch Hand
Posts: 808
Stephan van Hulst wrote:None of the answers are correct. The equals() contract explicitly states that x.equals(null) should return false. None of the implementations fulfill this requirement.

For any non-null reference value x, x.equals(null) should return false.
But suppose we insert a null check that returns false? Then it does appear that D is incorrect.

Joanne Neal
Rancher
Posts: 3742
16
Dennis Deems wrote:But suppose we insert a null check that returns false? Then it does appear that D is incorrect.

Do a search for SortOf in this forum and you will see that this has been spotted once or twice before.
It was mentioned in this errata thread (although not the bit about the null check). So it might be worth checking the Errata.

dennis deems
Ranch Hand
Posts: 808
Sebanti, can you please tell us what edition of K&B you are using?

Helen Ma
Ranch Hand
Posts: 451
When it comes to fulfill the equals and hashCode contract, it refers to the fact that if two objects are equals, their hash code must be the same. If two objects are not equal, their hash code can be different or the same.
In the other word, if the hash code is the same, the objects may or may not be the same. If the hash code is different, two objects must be different.

I think D is not correct, but the K & B master exam says it is correct.
If code.length * bal * rate is the same for two objects, the objects are equals according to D. In order to fulfill the contract, their hash codes must be the same. However, the hash code algorithm is code.length * bal as given by the question. These two objects may not have the same hash code even though they are equal. In my opinion D does not fulfill the contract.

For example Object A has (5,3,1) as their code.lenght, bal and rate while Object B has (1,3,5) for its attributes.
Are they equals based on D? Yes.
Are their hash code the same ? No. Object A's hashcode is 15, while Object B hashcode is 3.
Therefore D violates the contract that when two objects are equal, their hash code must be the same.

Sebanti Sanyal
Ranch Hand
Posts: 58
Dennis Deems wrote:Sebanti, can you please tell us what edition of K&B you are using?

Its 2008 edition for Java SE6

Sebanti Sanyal
Ranch Hand
Posts: 58

Helen Ma
Ranch Hand
Posts: 451
Hi, Sebati,

Do you think the answer is only C. A few people on the forum feel that the only answer is C, not D. I don't think we need to worry about x.equal (null) for the exam. If the string code is null, the code.length will throw a null pointer exception, that is not the objective of this question.

Sebanti Sanyal
Ranch Hand
Posts: 58
Helen Ma wrote:Hi, Sebati,

Do you think the answer is only C. A few people on the forum feel that the only answer is C, not D. I don't think we need to worry about x.equal (null) for the exam. If the string code is null, the code.length will throw a null pointer exception, that is not the objective of this question.

D is incorrect. If the null input was taken care of, C would be the correct answer.

Glen Iris
Ranch Hand
Posts: 174
What is the strategy for answering such a question? Having studied all the posts on this thread I am still no closer to knowing how/why this question works.

Can someone who knows the answer please state the step by step instructions that one should take in order to conclude an answer?

Thanks

Helen Ma
Ranch Hand
Posts: 451
• 1
Hi, Glen. In the exam, you may be asked whether a given code fulfill the equals and hashcode contract. For details, please refer to Chapter 7 of KB's book.
If the object's hashcode and equals method fulfills the contract, this object can be used as a key for HashSet / HashMap

To fulfill the contract:
1. if two objects are equal, their hashcode must be the same.
2. if two objects are not equals, their hashcode can be the same or different.
3. if two haschodes of two objects are the same, the two objects may or may not be equal.
4. if two haschodes of two objects are different, the two objects must be different.
For example, in the KB's practice exam book:

Class Chili{
String color ;
String hotness;

public Chili (String c, String h){ color=c; hotness=h;}

public boolean equals(Object o){
if ( ((Chili)o ).color = color && ((Chili)o).hotness = hotness
return true;
else
return false;
}

public int hashCode(){
return 100;
}

In this example, if you have two Chilis objects that you will put into a hashset or hashmap,
Chili c = new Chili("red", 1);

Chili c1 = new Chili ("green",2) ;

Will two of them be put in hashset as an element or hashmap as a key? Hashet only add unique objects (which are not equal to each other) while Hashmap take objects with unique key (keys that are not equal to each other.)
The answer is Yes. They have the same hashCode =100. Under the hashset or hashmap, there is a 2-D array called EntryTable.
For example, c is put in EntryTable[100]. Then, you will try to put c1 into the hashset/map. The compiler will look at c1's hashcode, 100. In EntryTable[100], there is a c. But that is ok. The compiler then compare if c is equal to c1. Based on the equals method, they are not equal. So, the compiler will create something like a list, put c and c1 in the list.

Of course, you can design any hash code algorithm for the hashCode method to make the Chili object having unique hashcode. For example, if you have a person object,
you can use SSN for hashcode as SSN is unique for everyone.

Therefore, if the hashcode and equals contract is fulfilled, objects can be added to hashset or map efficiently.

What can we do to violate this contract?
If two objects are equals, but their hashcode are different.

In a bad example, if the hashcode algorithm randomly generates numbers, this will violate the contract.

public int hashCode(){
Math.random(100); // for example..... I am not sure if this syntax is right.
}

If you have two red chili objects:
Chili c = new Chili ("red", 1); Chili c1 = new Chili("red", 1);

Their hashcodes can be different. c has 1 for its hashcode, c1 has 2 for its hashcode.

When you put c to a hashset or map, c is in EntryTable[1] and c1 is in EntryTable[2]!
But they are equal chili based on the equals() method.

Of course, these two chili objects can be add or put into hashset or hashmap without any compilation error. By doing that, you will put two identical objects (the equals method says if two chili objects have the same color and hotness, they are identical) into the hashset or map.

This is a bad hashCode() example.