| Author |
hashcode,equals()
|
Shiva Mohan
Ranch Hand
Joined: Jan 05, 2006
Posts: 465
|
|
Consider the following class: Which of the following options may be insterted at //1? a return true; b return theval%3 == 0? true :false; c return theval%2 == 0? true :false; d return ( (int)Math.random())*10%3 == 0? true :false; e return false; Answer given is option b.But i am having trouble on finding the correct answer on each option. suppose if i created, GoodOne s1=new GoodOne(); GoodOne s2=new GoodOne(); s1.theVal=2 s2.theVal=3 option 1: if the eqauls() method gives result true means the required hashcode contract is s1.hashCode()==s2.hashCode() but the getting values are 2==0 not equlal.so this option is false option 2: s1.equlas(s2) gives false result when i apply the value s1.theVal=2,so there is no hashcode requiremnet is the contract which is satisfied. s2.equlas(s1) s2.theVal=3 when i apply this value,the equals() method returns true means the required hashcode contract is s1.hashCode()==s2.hashCode().but the getting values are 2==0 not equlal.so i am getting false here source:enthuware
|
 |
Chandra Bhatt
Ranch Hand
Joined: Feb 28, 2007
Posts: 1707
|
|
Hi Shiva Mohan, See the private messages I have sent to you! Thanks,
|
cmbhatt
|
 |
Deepak Jain
Ranch Hand
Joined: Aug 05, 2006
Posts: 637
|
|
Here is the contract from Java doc Which of the following options may be insterted at //1? 1. If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result. 2. It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hashtables. So #1 is must. If two objects are equals hashCode must be equal Options: a) return true; If this is inserted in equals() then any two objects are always equal acc to equals method, But now their hashCodes will be different, So this does not satisfy the contract. Ex: g1 = new GoodOne(); g2 = new GoodOne(); g1.theVal = 1; g2.theVal = 2; So with above option g1.equals(g2) is true but g1.hashCode()!=g2.hashCode() because 1!=2 false So contract failed, So this option is incorrect. b) return theval%3 == 0? true :false; This option is correct, Becuase in hashCode() the hashCode of two objects will be same if theVal is divisble by 3, so now just take the reverse of this in equls() method, If two objects with theVal that is divisible by 3 then they are equal. g1.theVal = 1; g2.theVal = 2; Here g1.equals(g2) is false and g1.hashCode()!=g2.hashCode() but this is not mandatory, Unequal objects can have same hashCode, this will cause iefficient hashTables. So this option is correct. c) return theval%2 == 0? true :false; THis is straight forward incorrect becuase g1.equals(g2) is true only if theVal is divisible by 2 but then the hashCode() will be unequal whihc does not satisfy contract. d return ( (int)Math.random())*10%3 == 0? true :false; This is incorrect. Hope thie clears the confusion , I am confused now Just remember the first statement of contract. Thanks Deepak
|
SCJP, SCWCD, SCBCD
|
 |
Manfred Klug
Ranch Hand
Joined: Jun 04, 2007
Posts: 377
|
|
Hi Shiva, the only equals() method, which doesn't violate the contract, is e.
|
 |
Deepak Jain
Ranch Hand
Joined: Aug 05, 2006
Posts: 637
|
|
Hi, I did not see e option, I think both b and e are correct, Please correct me if am wrong. Contract is: 1) if a.equals(b) == true then a.hashCode() == b.hashCode() is MUST 2) if a.hashCode!=b.hashCode() then a.equals(n) == false is MUST Thanks Deepak
|
 |
Manfred Klug
Ranch Hand
Joined: Jun 04, 2007
Posts: 377
|
|
Originally posted by Deepak Jain: b) return theval%3 == 0? true :false; This option is correct, Becuase in hashCode() the hashCode of two objects will be same if theVal is divisble by 3, so now just take the reverse of this in equls() method, If two objects with theVal that is divisible by 3 then they are equal. g1.theVal = 1; g2.theVal = 2; Here g1.equals(g2) is false and g1.hashCode()!=g2.hashCode() but this is not mandatory, Unequal objects can have same hashCode, this will cause iefficient hashTables. So this option is correct.
You should use the rules from equals() too. This method violates g1.equals(g2) == g2.equals(g1)
|
 |
Manfred Klug
Ranch Hand
Joined: Jun 04, 2007
Posts: 377
|
|
Originally posted by Deepak Jain: I think both b and e are correct, Please correct me if am wrong.
Try it with different values for option b.
|
 |
Deepak Jain
Ranch Hand
Joined: Aug 05, 2006
Posts: 637
|
|
Thanks Manfred, Yes option #b fails reflexive property of equals(). Your correct, option e is correct. Thanks Deepak
|
 |
Chandra Bhatt
Ranch Hand
Joined: Feb 28, 2007
Posts: 1707
|
|
Hi everybody, Although the equals method does not abide to symmetric contract of the hashCode method, but as I think it is ok to be used in the context of key in the Map. equals will only be called once hashCode is equal for two object and ofcourse it is 0 for both so it does not matter whether you are doing like this.theValue %3 or ((GoodOne)o).theValue%3 because both will return 0. I agree that to compare two objects this equals method is not suitable anyway, because it violates the symmetric property that says For given two object references x and y if x.equals(y) =true then y.equals(x) must return true; I would appreciate any comment on this. Thanks in advance. Thanks, [ July 26, 2007: Message edited by: Chandra Bhatt ]
|
 |
Manfred Klug
Ranch Hand
Joined: Jun 04, 2007
Posts: 377
|
|
Originally posted by Chandra Bhatt: I agree that to compare two objects this equals method is not suitable anyway, because it violates the symmetric property
And as result it will violate the hashCode() contract sooner or later. Try it with g1.theVal = 0; g2.theVal = 2; g1.equals(g2) == true and g1.hashCode() != g2.hashCode()
|
 |
Chandra Bhatt
Ranch Hand
Joined: Feb 28, 2007
Posts: 1707
|
|
[Manfred] And as result it will violate the hashCode() contract sooner or later. Try it with g1.theVal = 0; g2.theVal = 2; g1.equals(g2) == true and g1.hashCode() != g2.hashCode() I am talking in the context of using the object of this class as key in the Map. If hashCode() mismatches, equals won't be used for object retrieval. And it hashCode is matched and it is 0, two objects are equal as the equals() method says so. What value you have given, the objects are not equal with respect to what hashCode() and equals() say. Thanks,
|
 |
Shiva Mohan
Ranch Hand
Joined: Jan 05, 2006
Posts: 465
|
|
Thank you guys for working in this problem.Many Many thanks to you chandra.Sorry for entering after a long time. Chandra! when entering 2,3 values for hashcode first how would you say,hashcodes is matched anf the result is 1. Still that part i don't get.please help. when entering 3,6 values for hashcode ,it will defnetely return 0. but what about other possibilities checkng.How would anyone know apply only 3 multiplies for this question for finding result. [ July 27, 2007: Message edited by: Shiva Mohan ] [ July 27, 2007: Message edited by: Shiva Mohan ]
|
 |
Chandra Bhatt
Ranch Hand
Joined: Feb 28, 2007
Posts: 1707
|
|
Shiv Mohan In this example, if you see I first talked about simply equals() method use that is not used in the Map context (not as a key in the Map). So hashCode() is of no use there. I just tried to show you how symmetric contract is violated there. In case theValue is 3 and 2 for two objects, hashCode is not matched and the comparison fails in the first round (here I am talking about Map context). Thanks,
|
 |
Manfred Klug
Ranch Hand
Joined: Jun 04, 2007
Posts: 377
|
|
Originally posted by Chandra Bhatt: What value you have given, the objects are not equal with respect to what hashCode() and equals() say.
They are equal according to the equals() method. (0 % 3) == 0 -> true
|
 |
 |
|
|
subject: hashcode,equals()
|
|
|