This week's book giveaway is in the OCAJP 8 forum. We're giving away four copies of OCA Java SE 8 Programmer I Study Guide and have Edward Finegan & Robert Liguori on-line! See this thread for details.
My question is regarding this passage of K&B (SCJP 6 Edition) in page 550:
You must also be able to recognize an appropriate or
correct implementation of hashCode(). This does not mean legal and does not even
mean efficient. It's perfectly legal to have a terribly inefficient hashcode method
in your class, as long as it doesn't violate the contract specified in the Object class
documentation (we'll look at that contract in a moment). So for the exam, if you're
asked to pick out an appropriate or correct use of hashcode, don't mistake appropriate
for legal or efficient.
This is what I thought:
- Regarding appropriate or correct implementations of hashCode(), I think the idea is that the implementation must abide by the contract with equals(), so that if a.equals(b) is true, then hashCode(a) == hashCode(b) must also be true.
- However, a legal implementation would simply mean that the method is a syntactically correct override of hashCode() in the Object class.
But I am confused by the text which I have marked bold above: It implies that in order for an implementation of hashCode() to be legal it must conform to the contract. Then, it goes on later (last sentence) to say that legal and appropriate is not the same.
What is the difference between legal and correct (or appropriate)?
All code in my posts, unless a source is explicitly mentioned, is my own.
"Legal" means that it is valid Java code (which will not cause a compiler error). "Correct" in the case of the hashCode() method means that the implementation is according to the hashCode() contract.
This is what the text means: If the exam asks you to pick the implementation that's correct, it doesn't mean that you should look for code with syntax errors, and it doesn't mean you have to look if the code is efficient. It's asking you to pick the one without compiler errors, which conforms to the hashCode contract, but which is not necessarily efficient.
Thank you Jesper. That's what I thought. I was confused by the part of the text that says: "It's perfectly legal to have a terribly inefficient hashcode method in your class, as long as it doesn't violate the contract specified in the Object class documentation." I think that maybe "legal" above should be replaced by "appropriate" or "correct" just to avoid misunderstandings.
So an implementation of hashCode() could be legal but not correct, whereas if it is correct (appropriate) is must necessarily be legal, plus it must satisfy the contract.
This is horribly inefficient but legal. If two objects have an instance variable x with the value 8 the objects are equal. If one has the value 8 and the other has the value -920, they still have the same hash value.
Now the hash value depends on x and makes the implementation efficient.
Joined: Dec 16, 2008
There are 3 concepts at hand: Legal, appropriate, and efficient. Both of the implementations that you give are legal and appropriate. The second one is more efficient than the first one, but it would even be more efficient if you dropped the 1492, as multiplying x by any factor doesn't improve the efficiency of the hashCode. It actually hurts it, because you need to perform a multiplication every time you need to calculate the hashCode, whereas there are no benefits due to the fact that the number of buckets is not increased (and therefore the rate of collisions is not reduced) using 1492*x vs using x.