Here is the code taken from K&B book chapter 7: With reference to line#5, it states in the book that(taken from pg 564 bottom para):
Why didn't we find the Cat key String? Why did it work to use an instance of Dog as a key, when using an instance of Cat as a key failed? It's easy to see that Dog overrode equals() and hashCode() while Cat didn't.
I tried changing the program a bit and this is what I got: 1) I commented the equals() and hashCode() used in Dog class, but the code runs and produces the same output. 2) If this code set is used in the original program:
instead of this one given in the book:
It produces the expected output (Cat key).
So, I feel with regards to 1) and 2), its really not a MUST for a class to override the equals() and hashCode() for using its object as a part of the key. Please comment and explain why this behaviour?
Joined: Oct 10, 2007
Can someone answer my doubt regarding equals() and hashCode() overriding?
Sorry that I am answering your question with another question (though it's on topic): If you use instanceof plus a member var to check for equivalence, couldn't you end up with a Lab named 'Sebastian' and a ChocolateLab 'Sebastian' that are in fact different dogs but evaluate to being equal? I guess you could code that Lab is an interface or something, but shouldn't we use some sort of Class.forName (not sure if that's the way to do this) to check that they are the exact same type and not a subtype?
Dog | Lab | ChocolateLab
Joined: Oct 09, 2007
Oh, and I believe I do have the answer (though I'm freaking out to take test tomorrow so I only looked quickly) It seems that you are in fact passing in the same exact object of type Cat (whereas they did a 'new' Cat) So if you don't have equals and hashcode methods overriden what happens is that the good ol' Object class uses its version. For the equals it actually implements this by saying (we'll call your exact Cat object 'missy') is missy==missy meaning does missy object refer to the same exact object missy and yes it does! However, in their code using the 'new' a whole new Cat is created using a different part of memory and the whole nine yards! Please google DocJar, go to the Object class and click the source option which will show you the actual source code. Kelvin ( a regular in here) tip'd me off to this cool site. Don't worry, the code is actually quite easy on the eyes and will show you a lot as all of us test takers are expected to know the semantics of Object's methods intimately. Good luck and I hope I answered your question
Joined: Oct 10, 2007
Oh! Thanks, Nico. I somehow oversaw that the same object was used. Thanks for pointing it out. Now it makes sense.
The explanation in the book doesn't make sense to me.
Why didn't we find the Cat key String? Why did it work to use an instance of Dog as a key, when using an instance of Cat as a key failed?
It's easy to see that Dog overrode equals() and hashCode() while Cat didn't.
The instance of dog was assigned to the variable d1. When the get method was called, the variable d1 was passed as argument. That's why it could retrieve a dog.
The cat instance had no variable, it was created on the fly. So the get method couldn't find it because it didn't have a variable to refer to it. Calling uses a different object, a new Cat object that has nothing to do with the first cat, that's why the value in the map can't be found.
Now how can overriding equals() and hashcode() affect that?
(maybe if you made it so that any Cat created with the same name would be essentially the same Cat, then you could pass a new one to the get method and the value would be retrieved?)