Source: Mock exam engine for 1.4 Exam by Khalid A. Mughal and Rolf W. Rasmussen

Given the following class, which are correct implementations of the hashCode() method?

class ValuePair { public int a, b; public boolean equals(Object other) { try { ValuePair o = (ValuePair) other; return (a == o.a && b == o.b) || (a == o.b && b == o.a); } catch (ClassCastException cce) { return false; } } public int hashCode() { // Provide implementation here. } }

The hashCode() method must be implemented in a certain way, which depends on how equals() is implemented in the same class: if equals() returns true, then the hashCode of the objects that are compared must be the same.

See the API documentation of Object.hashCode() for more information.

And this website also explains it: Equals and Hash Code in Java [ September 16, 2008: Message edited by: Jesper Young ]

The Rule is that if the 2 objects are equal then the hashcode must be the same for both objects. (The reverse is not true. Just because two objects have the same hash code they do not have to be equal.)

I like to make up specific values to try for these:

Equality scenario 1:

Object A +++++++++ + a = 5 + + b = 6 + +++++++++

Object B +++++++++ + a = 5 + + b = 6 + +++++++++

Equality scenario 2:

Object A +++++++++ + a = 3 + + b = 2 + +++++++++

Object B +++++++++ + a = 2 + + b = 3 + +++++++++

Now the question is which expression guarantees that you'll get an identical hash code under both scenarios.

return 0

This ALWAYS give the same hashCode including when you have equal objects, so this must be correct.

return a

Scenario 2 shows a situation where the a's are different and the objects are deemed equal, so "return a" fails.

return a+b

Under both equality scenarios the sum of a and b are the same, so this choice is correct.

return a-b

The sign of the result will be different under equality scenario 2. This option fails. (return Math.abs(a-b) would work)

return a^b

XOR is a bitwise "difference detector". It flips bits on when bits in corresponding slots in 2 numbers are different. (e.g. one is a 1 and the other is a 0). Under scenario 1 a^b will clearly return the same value for both objects. Under scenario 2 the order of the arguments is reversed, but since XOR is commutative it doesn't matter; a^b is the same as b^a. This choice is correct.

return a<<16|b

This one makes me glad that bitwise shift operators are off the exam. I'm sure that there must be a better way to proceed, but I set out to find a situation where the objects could be the same and different hashcodes could still be produced. Scenario 1 is trivial (tautology). Scenario 2 is interesting. I assumed that a was all 1's and b was a pattern of repeating 1's and 0's. When you left shift you zero fill so this gave me

11111111111111110000000000000000 or 10101010101010101010101010101010 -------------------------------- 11111111111111111010101010101010

and

10101010101010100000000000000000 11111111111111111111111111111111 or -------------------------------- 11111111111111111111111111111111

Since different hashcodes can be produced even when the objects evaluate as equal, this option fails.