• Post Reply Bookmark Topic Watch Topic
  • New Topic

hard/tricky hashCode/equals question  RSS feed

 
Jeanne Boyarsky
author & internet detective
Marshal
Posts: 36659
475
Eclipse IDE Java VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
No, I don't have a question. Scott and I decided not to include this question in our upcoming practice questions book because it requires knowledge of a fact that isn't on the exam. We did think it might spark some good discussion so posting it here. So discuss. What do you think is the answer and why.

----------------------------------------------------------------

How many of the following values can fill in the blank for the class to correctly implemented?



I. 5, false
II. 5, true
III. new Random().nextInt(), false
IV. new Random().nextInt(), true

A. 0
B. 1
C. 2
D. 3
 
praveen kumaar
Ranch Hand
Posts: 450
22
Android Chrome Eclipse IDE Google App Engine Java Notepad Oracle Ubuntu Windows
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
3 is the answer which are-
I. 5, false
II. 5, true
III. new Random().nextInt(), false
5,true--->since equality needs the must condition of equality of hashCode(of 2 object compared).so if we our equal method return true forever then the hashcode must be same always which here is satisfied.

new Random().nextInt(), false--->here equal method is always returning false but as accordingly with rules still we can have our hashcodes method to return same integer or a varying one which is satisfied here as new Random().nextInt() will return a random integer but on next call  it can be the same or different one.

5, false--->same answer applies here as for "new Random().nextInt(), false".

new Random().nextInt(), true--> it cannot be the answer for correct implementation as our equal method is returning true forever which requires the equality of hashcode forever but in this case new Random().nextInt() will return a fluctuating integer...

Am i right jeanne?
please correct me if i am wrong at any point.

Kind Regards,
Praveen.

 
Jeanne Boyarsky
author & internet detective
Marshal
Posts: 36659
475
Eclipse IDE Java VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Praveen,
Nope, but a cow for trying. Take a look at the method signature for hashCode. Then think about what happens if the @Override is and isn't there.
 
praveen kumaar
Ranch Hand
Posts: 450
22
Android Chrome Eclipse IDE Google App Engine Java Notepad Oracle Ubuntu Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Aah..what a dumb mistake,thanks jeanne.
if override is present then it will not compile though if it's not present then i think
I.5, false and III.new Random().nextInt(),false can be the answer as hash code will be different for different instances which will cause equal to return false every time.

how about now?

kind regards,
Praveen.
 
Tobias Bachert
Ranch Hand
Posts: 73
12
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Currently you are thinking exclusively about the hashcode contract, don't forget about the equals contract.
Edit: Made answer way less specific to not give the answer.
 
praveen kumaar
Ranch Hand
Posts: 450
22
Android Chrome Eclipse IDE Google App Engine Java Notepad Oracle Ubuntu Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hmmm yes their will be the case when my 2 soln will fail in respect of fulfilling reflexivity for equal contract..finally i think none,0, will be the answer..
Is it?
 
Jeanne Boyarsky
author & internet detective
Marshal
Posts: 36659
475
Eclipse IDE Java VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hint: If removing the @OVerride, none is not the answer. Now the question is can you figure out why .
 
praveen kumaar
Ranch Hand
Posts: 450
22
Android Chrome Eclipse IDE Google App Engine Java Notepad Oracle Ubuntu Windows
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jeanne,it's now creating a confusion for me.i am interpreting all the options below:
CASE 1: 5, false
it would fail for the reflexivity i.e.,stickerA.equals(StickerA) should return true but it will not.

CASE 2: 5,true
it would fail to meet equals contract for non-nullity i.e,StickerA.equals(null) should return false but it will not.

CASE 3:new Random().nextInt(),false
it would again fail for the reflexive property.

CASE 4:new Random().nextInt(),true
and finally it would fail for non-nullity.

however,i really don't understand the role of hashCode(Object o) here.that's why i put the term confusion above..

jeanne,can you please end up the suspense now(followed by an answer and elaboration).

Kind Regards,
Praveen.
 
praveen kumaar
Ranch Hand
Posts: 450
22
Android Chrome Eclipse IDE Google App Engine Java Notepad Oracle Ubuntu Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
i am still waiting jeanne...
 
praveen kumaar
Ranch Hand
Posts: 450
22
Android Chrome Eclipse IDE Google App Engine Java Notepad Oracle Ubuntu Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
you didn't answer the question,jeanne.
 
Jeanne Boyarsky
author & internet detective
Marshal
Posts: 36659
475
Eclipse IDE Java VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
First of all, I don't check the forums when at work. Let's not bump things unless it has been 24 hours.

What is the method signature of hashCode(). Is it hashCode(Object o)? Your post seems to imply that it is. Check.

Also, I'm trying to wait until January to post the answer to see if others want to try it out.
 
Stefan Evans
Bartender
Posts: 1834
10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The trick Jeanne pointed out is that the hashCode method defined here does not override the hashCode method defined in Object because it has a different signature.
So with the @Override annotation present, it should fail to compile, thus none of the options will make a correctly implemented class.
Personally I hate this style of trick question.

@praveen You've made a pretty good argument there.  I'm convinced.
Jeanne did say that at least one of the answers is valid if you remove the override annotation, but you have eliminated them all - just with the requirements for the equals method contract.

What about if we changed the equals method to


i.e. I've gotten rid of the "null" argument with this change.
How does that change the answer now?
 
praveen kumaar
Ranch Hand
Posts: 450
22
Android Chrome Eclipse IDE Google App Engine Java Notepad Oracle Ubuntu Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jeanne Boyarsky wrote:First of all, I don't check the forums when at work. Let's not bump things unless it has been 24 hours.

What is the method signature of hashCode(). Is it hashCode(Object o)? Your post seems to imply that it is. Check.

Also, I'm trying to wait until January to post the answer to see if others want to try it out.

you get me wrong,jeanne.
please,apology for anything if my post rankled you.i really didn't intended to do so(if it was,to anyone).
and i do well know the signature of hashCode().i mentioned it in my earlier post but what i am asking is-is their any role of new hashCode(Object o) in Sticker even after override annotation is removed because it will not be called anywhere in the code and another thing is it was given a name hashCode and so is intending to calculate hashCode for an instance but it's not and thus creating a confusion.

Kind regards,
Praveen.
 
praveen kumaar
Ranch Hand
Posts: 450
22
Android Chrome Eclipse IDE Google App Engine Java Notepad Oracle Ubuntu Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stefan wrote:I've gotten rid of the "null" argument with this change.
How does that change the answer now?

@Stefan i think that's a very weak correction,i will not change my answer though.here is the reasoning-->for case 1st and 3rd where equals is returning false for ever,in both the option,it will not met the reflexive contract for both the cases.now for remaining 2 cases 2nd and 4th the equals is returning true every time for non-null instances,here it will loose the symmetry as suppose i put an instance of Animal in the argument of the stickers equals method then it will return true so as per the equals contract it was required to fulfill symmetry which is Animal.equals(Sticker) should also return true but it will depend totally on the policy of equals method of Animal and thus is not a good option for the good implementation and along with the worst thing is the dependence of sticker class on a Animal class which is declining the contracts of OOPS-abstraction.

Thank You.

Kind regards,
Praveen.
 
Piet Souris
Rancher
Posts: 1844
61
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Apart from al the contracts about symmetry and the like, and sticking to Jeannes text in the opening post, I did some experiments. And I am puzzled by the outcomes, I must say.

Here is what I did:

And the outcome was:
run:
5, true
5, true
5, true
5, true
5, true
map<B, I>: Boyarski2: 4: 4
map<B, I>: Boyarski2: 1: 1
map<B, I>: Boyarski2: 2: 2
map<B, I>: Boyarski2: 3: 3
map<B, I>: Boyarski2: 5: 5
map<I, B>: 1: Boyarski2: 1
map<I, B>: 2: Boyarski2: 2
map<I, B>: 3: Boyarski2: 3
map<I, B>: 4: Boyarski2: 4
map<I, B>: 5: Boyarski2: 5
*************************************
keyset contains new Boyarski2(10)? : false
valuesin map<I, B>: [Boyarski2: 1, Boyarski2: 2, Boyarski2: 3, Boyarski2: 4, Boyarski2: 5]
values contain new Boyarski(10)? : false
B(10) equals B(12)? false
+++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++
5, false
5, false
5, false
5, false
5, false
map<B, I>: Boyarski2: 1: 1
map<B, I>: Boyarski2: 3: 3
map<B, I>: Boyarski2: 5: 5
map<B, I>: Boyarski2: 2: 2
map<B, I>: Boyarski2: 4: 4
map<I, B>: 1: Boyarski2: 1
map<I, B>: 2: Boyarski2: 2
map<I, B>: 3: Boyarski2: 3
map<I, B>: 4: Boyarski2: 4
map<I, B>: 5: Boyarski2: 5
*************************************
keyset contains new Boyarski2(10)? : false
valuesin map<I, B>: [Boyarski2: 1, Boyarski2: 2, Boyarski2: 3, Boyarski2: 4, Boyarski2: 5]
values contain new Boyarski(10)? : false
B(10) equals B(12)? false
+++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++
random, true
random, true
random, true
random, true
random, true
map<B, I>: Boyarski2: 4: 4
map<B, I>: Boyarski2: 2: 2
map<B, I>: Boyarski2: 5: 5
map<B, I>: Boyarski2: 1: 1
map<B, I>: Boyarski2: 3: 3
map<I, B>: 1: Boyarski2: 1
map<I, B>: 2: Boyarski2: 2
map<I, B>: 3: Boyarski2: 3
map<I, B>: 4: Boyarski2: 4
map<I, B>: 5: Boyarski2: 5
*************************************
keyset contains new Boyarski2(10)? : false
valuesin map<I, B>: [Boyarski2: 1, Boyarski2: 2, Boyarski2: 3, Boyarski2: 4, Boyarski2: 5]
values contain new Boyarski(10)? : false
B(10) equals B(12)? false
+++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++
random, false
random, false
random, false
random, false
random, false
map<B, I>: Boyarski2: 2: 2
map<B, I>: Boyarski2: 5: 5
map<B, I>: Boyarski2: 1: 1
map<B, I>: Boyarski2: 4: 4
map<B, I>: Boyarski2: 3: 3
map<I, B>: 1: Boyarski2: 1
map<I, B>: 2: Boyarski2: 2
map<I, B>: 3: Boyarski2: 3
map<I, B>: 4: Boyarski2: 4
map<I, B>: 5: Boyarski2: 5
*************************************
keyset contains new Boyarski2(10)? : false
valuesin map<I, B>: [Boyarski2: 1, Boyarski2: 2, Boyarski2: 3, Boyarski2: 4, Boyarski2: 5]
values contain new Boyarski(10)? : false
B(10) equals B(12)? false
+++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++
BUILD SUCCESSFUL (total time: 1 second)

What I don't understand is the constant outcome of the last four lines:
keyset contains new Boyarski2(10)? : false
valuesin map<I, B>: [Boyarski2: 1, Boyarski2: 2, Boyarski2: 3, Boyarski2: 4, Boyarski2: 5]
values contain new Boyarski(10)? : false
B(10) equals B(12)? false

No Boyarski equals any other Boyarski, no matter whether equals returns true or false. So either I made one or more programming errors, or there are things that are beyond me (probably both).  Hmmm....
 
praveen kumaar
Ranch Hand
Posts: 450
22
Android Chrome Eclipse IDE Google App Engine Java Notepad Oracle Ubuntu Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
piet wrote:What I don't understand is the constant outcome of the last four lines:
keyset contains new Boyarski2(10)? : false
valuesin map<I, B>: [Boyarski2: 1, Boyarski2: 2, Boyarski2: 3, Boyarski2: 4, Boyarski2: 5]
values contain new Boyarski(10)? : false
B(10) equals B(12)? false
No Boyarski equals any other Boyarski, no matter whether equals returns true or false. So either I made one or more programming errors, or there are things that are beyond me (probably both).  Hmmm....

That's because the Boyarski2 didn't override the hashCode() i.e.,the class used a hashCode implementation of the Object class which return a unique integer for every instance.and contains needs to fulfill both the contracts-equality of hash codes and others (reflexive,symmetry...) for containing xyz(the same contract is needed for equals(Object o) also).but since hash code are all different here for different instances so contains is returning false regularly.

Kind regards,
Praveen.
 
Piet Souris
Rancher
Posts: 1844
61
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Be that as it may, I checked whether two Boyarski's were equal and I get false, even when the equals method returns true in all cases. So either I made a programming error, or else something else is going on. The map part was intended to find out if the buckets were nicely filled, which they were, so the non overridden hashCode() is being used here. Still puzzled, I hoped to get some clues as to whether this hashCode(Object o) is being used somewhere, no sign of it yet.
 
Tobias Bachert
Ranch Hand
Posts: 73
12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You forgot to set eq for the objects with id 10 and 12. As a result, you are always comparing objects with eq == false.

Regarding the question of the thread:
I totally agree with praveen, I see no way to implement a valid equals method with the provided options. Currently the only valid option (except for something like 'return obj instanceof Sticker && hashCode() == obj.hashCode()') would be to restore the version of Object#equals (return obj==true) as everything else would violate either the equals or the hash code contract.
 
praveen kumaar
Ranch Hand
Posts: 450
22
Android Chrome Eclipse IDE Google App Engine Java Notepad Oracle Ubuntu Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Piet,
yes,the hashCode(Object o) is redundant here and i think it's just used for puzzling one's mind specially in exam so you can remove it.
you are comparing new Boyarski2(10) with new Boyarski2(12) through equals,in the each iteration you are creating a sole new instance that has nothing  to do with the collection or map(or the keys or values of these collection),in fact you design the equals in such a way that when equal is invoked on the instance it needs to check for the boolean value of variable random which can only be true if you set it via the setter or else it is false by default.and in the comparison you just created the 2 instances but not set their variable random that's why equal is returning false every time.
try one thing set the random to true in your code and see the difference.

Kind regards,
Praveen.
 
Stefan Evans
Bartender
Posts: 1834
10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Piet Souris wrote:Be that as it may, I checked whether two Boyarski's were equal and I get false, even when the equals method returns true in all cases. So either I made a programming error, or else something else is going on. The map part was intended to find out if the buckets were nicely filled, which they were, so the non overridden hashCode() is being used here. Still puzzled, I hoped to get some clues as to whether this hashCode(Object o) is being used somewhere, no sign of it yet.


Programming Error. 

Where is the Boyarski class?  It ain't in this code snippet.

Maybe it should be Boyarski2?


 
Piet Souris
Rancher
Posts: 1844
61
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hmm... my code was not what one would call 'error free'. Thanks guys for pointing it out. To quote the Italian captain from 'allo 'allo: whatamistakadamaka.  

Well, meanwhile up to Boyarski3. Since the Override gives a compile error, I hoped to prove the existence of a private method. After all, we know Jeanne as a serious person who would not let us chase for ghosts! (hmm). But whatever I tried, no sign of it, and overriding the normal hashCode and equals, leaving all contract aspects out, using hash maps and sets, I saw nothing that I could not explain. So I throw the towel.
 
Igor Soudakevitch
Author
Ranch Hand
Posts: 38
7
Android Java Netbeans IDE
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Without thinking and purely automatically I would say none of the available options work... simply because Joshua Bloch told us "Always override hashCode when you override equals."
 
praveen kumaar
Ranch Hand
Posts: 450
22
Android Chrome Eclipse IDE Google App Engine Java Notepad Oracle Ubuntu Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Igor Soudakevitch wrote:..."Always override hashCode when you override equals."

one line answer to the question!
the best part is,as per effective..,sticker is stateless and thus all its instances are functionally equal which force it to be a singleton along with the same implementation of the "hashcode() and equals()" that it inherited from object.

Kind Regards,
Praveen.
 
Jeanne Boyarsky
author & internet detective
Marshal
Posts: 36659
475
Eclipse IDE Java VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stefan Evans wrote:Jeanne did say that at least one of the answers is valid if you remove the override annotation, but you have eliminated them all - just with the requirements for the equals method contract.

You are right Praveen. Cow for you. I didn't think about null when I was creating the question.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!