| Author |
equals() and hashCode() from Java.Inquisition
|
Himanshu Kansal
Ranch Hand
Joined: Jul 05, 2009
Posts: 257
|
|
Hello,
I saw this question in Java.Inquisition for SCJP 5:
Given two objects a and b of the same class, and if equals() and hashCode() are implemented correctly for that class, which of the following must hold true?
The options were:
A. If a.equals(b) then a.hashCode() == b.hashCode()
B. If !a.equals(b) then a.hashCode() == b.hashCode()
C. If a.equals(b) then a.hashCode() != b.hashCode()
D. If !a.equals(b) then a.hashCode() != b.hashCode()
My thoughts:
A : References a and b may or may not point to the same object. Since they may not point to the same object, hashCode can be different.
B : References a and b definitely do NOT point to the same object. Hence hashCodes cannot be same.
C : References a and b may or may not point to the same object. Since they may point to the same object, hashCode might be same.
D : References a and b definitely do NOT point to the same object. Hence hashCode cannot be same.
What J.I gives as correct answer is not my problem actually. I would like to know if I am not missing something. According to the hashCode contract if equals gives true, then hashCode must give same int result for both objects. But it is not necessary that it will give so. I would have marked D as an answer. Any ideas on this?
Regards
|
Experience and talent are independent of age
|
 |
Lucas Smith
Ranch Hand
Joined: Apr 20, 2009
Posts: 804
|
|
Just remember that:
If a.equals(b)==true => a.hashCode()==b.hashCode()
It's the hashCode() contract
I can add that:
a.hashCode()!=b.hashCode() => a.equals(b)==false
|
SCJP6, SCWCD5, OCE:EJBD6.
BLOG: http://leakfromjavaheap.blogspot.com
|
 |
Himanshu Kansal
Ranch Hand
Joined: Jul 05, 2009
Posts: 257
|
|
Yes, that's true. I stated a statement from the contract myself. But then it is only a contract, or said so as given in the documentation. It is no hard and fast rule. The compiler does not care about it. Moreover, isn't it true that hashcode refers directly to an object and equals to the reference?
Isn't the question ambiguous if it can have multiple answers when asked for 1?
Regards
|
 |
Himanshu Kansal
Ranch Hand
Joined: Jul 05, 2009
Posts: 257
|
|
The documentation also states that:
The equals method for class Object implements the most discriminating possible equivalence relation on objects; that is, for any reference values x and y, this method returns true if and only if x and y refer to the same object (x==y has the value true).
Does this mean that equals should return true ONLY when references point to the SAME object? If yes, then this does not happen actually.
Am I confusing myself?
Regards
|
 |
Lucas Smith
Ranch Hand
Joined: Apr 20, 2009
Posts: 804
|
|
The second Tip:
If you override hashCode() => override equals()
equals() should be for meaningfull (programmer dependent) equilibrium between objects.
|
 |
Anastasia Sirotenko
Ranch Hand
Joined: Jul 20, 2009
Posts: 64
|
|
Himanshu Kansal wrote:
According to the hashCode contract if equals gives true, then hashCode must give same int result for both objects. But it is not necessary that it will give so. I would have marked D as an answer. Any ideas on this?
It is nessessary that if two objects are equal they have the same hashCode();
Though if objects are not equal they still can have same hashcode - it is legal and appropriate to do so.
The thing is - some collections store and search objects according to their hashCode. If all objects have their hashcode as accurate as possible (so only equal objects have equal hashcode) than searching in hashed collection is much faster. Still it will be appropriate to have all hashcodes of same value, but it will decrease search speed in them collections. Look at hashcode as you zipcode for postmaster 8]
But if for some disaster hashcodes of equal objects will differ, you will never find your object in collection, like if someone marked a letter for you with wrong zipcode and postmaster in Zimbabwe now searches for Mr. Himanshu Kansal 8]
With best regards
|
[SCJP 6.0]
|
 |
Nitish Bangera
Ranch Hand
Joined: Jul 15, 2009
Posts: 536
|
|
Given two objects a and b of the same class, and if equals() and hashCode() are implemented correctly for that class, which of the following must hold true?
The options were:
A. If a.equals(b) then a.hashCode() == b.hashCode()
B. If !a.equals(b) then a.hashCode() == b.hashCode()
C. If a.equals(b) then a.hashCode() != b.hashCode()
D. If !a.equals(b) then a.hashCode() != b.hashCode()
The only true thing is A.
B.its said the equals and hashcode methods are correctly implemented. Assumption same hashcode object go in a single bucket.but still the framing of the question is wrong. equals is not checked first.
B. If !a.equals(b) then it might return a.hashcode()==b.hashcode() and might not also D. Its not perfect. Its based on the hashcode implementation. If the object hashcode implementation is used then every object will have its own separate hashcode value i.e in a hashmap every object will land in its own bucket.Or if you override the hashcode method n make a provision so that objects having same hashcode land in the same bucket then B is true.
C is false anyway.
1 more thing, a and b are not objects, they are references.
|
[ SCJP 6.0 - 90% ] , JSP, Servlets and Learning EJB.
Try out the programs using a TextEditor. Textpad - Java 6 api
|
 |
Himanshu Kansal
Ranch Hand
Joined: Jul 05, 2009
Posts: 257
|
|
Anastasia Sirotenko wrote: It is nessessary that if two objects are equal they have the same hashCode();
That's only by the contract. The compiler does not complain about it. Hence it is not necessary.
Nitish Bangera wrote:1 more thing, a and b are not objects, they are references.
I called them references myself (the starting post of the thread -> My Thoughts).
Nitish Bangera wrote: The only true thing is A.
Supported by nothing substantial but the contract.
My point is that the compiler won't refuse to compile if things do not go by the contract. To state an option that must be true we need to have a definitive logic; not some policy.
Regards
|
 |
Henry Wong
author
Sheriff
Joined: Sep 28, 2004
Posts: 16811
|
|
Himanshu Kansal wrote:Does this mean that equals should return true ONLY when references point to the SAME object? If yes, then this does not happen actually.
No. You can prove this simply by creating two different strings with the same value -- and see that the equals() method does indeed returns true.
Now... if you mean does this apply for the java.lang.Object class, then yes, that is what the equals() method for that class does -- returns true only if it is the same instance.
Henry
|
Books: Java Threads, 3rd Edition, Jini in a Nutshell, and Java Gems (contributor)
|
 |
Henry Wong
author
Sheriff
Joined: Sep 28, 2004
Posts: 16811
|
|
Himanshu Kansal wrote:
My point is that the compiler won't refuse to compile if things do not go by the contract. To state an option that must be true we need to have a definitive logic; not some policy.
Keep in mind that just because something isn't enforced, doesn't mean that it should not be done. If you have a data object, with a definition of equality, or even comparibilty, why shouldn't you take 15 minutes to implement equals(), hashCode(), and/or compareTo() method correctly as stated by the contract?
Better 15 minutes of effort during development now, than an hour of defending yourself during a code review later.
Henry
|
 |
Himanshu Kansal
Ranch Hand
Joined: Jul 05, 2009
Posts: 257
|
|
Henry Wong wrote:No. You can prove this simply by creating two different strings with the same value -- and see that the equals() method does indeed returns true.
Exactly. Happy to hear a familiar statement. Thanks
Regards
|
 |
Nitish Bangera
Ranch Hand
Joined: Jul 15, 2009
Posts: 536
|
|
My point is that the compiler won't refuse to compile if things do not go by the contract. To state an option that must be true we need to have a definitive logic; not some policy.
the definitive logic is given in the question that for the class equals and hashcode are correctly implemented for that class. Based on that logic and some policy included we can deduce the answer as A.
Well anyways as henry said if we have 2 objects of the same value then a.equals(b) will be true and the objects will have a different hash code. This doing it for testing is ok.We can verify this but in real world problem solving using programming this would be a blunder. Just because Apple and watermelon have black seeds that doesn't make them equal to each other.
|
 |
Himanshu Kansal
Ranch Hand
Joined: Jul 05, 2009
Posts: 257
|
|
Does "implemented correctly" necessarily mean that it follows the policy? Shouldn't it go with respect to the compiler.
I perfectly understand that to answer the question, we need to refer the contract. But that is only to get the correct theoretical answer. In my opinion it should be enforced somehow and not just left for the developers to practice by choice.
Regards
|
 |
Nitish Bangera
Ranch Hand
Joined: Jul 15, 2009
Posts: 536
|
|
|
Well don't worry about the enforcing thing as SCJP 6 will be off and SCJP+ will be coming where we will actually code to get the certificate. But see coding all depends on real world problems. If they say equals and hashcode are implemented correctly which can mean implicitly that they are trying for a hashmap.
|
 |
Anastasia Sirotenko
Ranch Hand
Joined: Jul 20, 2009
Posts: 64
|
|
Himanshu Kansal wrote:Does "implemented correctly" necessarily mean that it follows the policy? Shouldn't it go with respect to the compiler.
I perfectly understand that to answer the question, we need to refer the contract. But that is only to get the correct theoretical answer. In my opinion it should be enforced somehow and not just left for the developers to practice by choice.
If you doubting for exam terms, then "implemented correctly" means following policy, "is legal" term is used regarding compiler.
So "legal but not implemented correctly" refers to code that compile well but can behave unpredictably in runtime.
|
 |
 |
|
|
subject: equals() and hashCode() from Java.Inquisition
|
|
|