There are multiple concepts involved here:
1. Observe that Book class has overridden equals() method but hasn't overridden hashCode() method. The way equals method is coded here makes two Book objects equal if their isbn is equals. However, their hashCode value will be different because Object class's hashCode method returns unique hashcode for every object.
2. In the main method, a Book object is stored in BookStore. The same Book object is being used to retrieve the numberofcopies value. Since the object that was stored in the Map and the object that was used to retrieve the value from the map are the same object, their hashCode will be the same and hence map will be able to find it among its name-value pairs. Thus, this will print 10.
3. Next, a new Book object is created. Note that its hashcode will be different from the previously created book object. But as per equals() method of Book, they are equal because their isbn are same. When you try to use the new Book object to find the value, map will not find anything because of a different hashcode. So map.get() will return null.[what difference does this make if the newly created Book object isn't even placed in BookStore. Even if the newly created Book object has ISBN if 112, it seems that map.get() will return null since it wasn't placed in BookStore]
4. The return type of the method is an int (and not an Integer). But map.get always returns an object (not a primitive.) So auto-unboxing will try to convert null into an int, which will throw a NullPointerException.[what method are they referring to?]
5. There is no warning at compilation because all the operations are valid.
Marriage Made in Heaven
http://www.youtube.com/user/RohitWaliaWedsSonia
"Any fool can write code that a computer can understand. Good programmers write code that humans can understand." --- Martin Fowler
Please correct my English.
No you're changing the local copy of the reference but you're not changing anything in the Map.Gouri Kumari wrote:[...] Even if second book object is not added to bookstore, reference variable 'b' refers to it in statement 45. Therefore, the key 'b' in map now refers to the second book object .
Even with a proper implementation of the hashcode and equals methods it will throw a NullPointerException if you call getNumberOfCopies() with a Book that is not in the Map. I explained the reason for that Exception in my previous post.Gouri Kumari wrote: So for Sandra's code, I do not think adding or not adding second object to the map is the real reason for the null pointer exception. I think defining equals and hashcode methods are the real key to the issue. When hashcode method is not overridden(hash codes are different) or ISBN value is changed from 111 to 112(equals method return false), map cannot find any value(number of copies) for the second object, therefore map.get() returns null. Can someone correct me, if my logic is wrong.
No you're changing the local copy of the reference but you're not changing anything in the Map.
Even with a proper implementation of the hashcode and equals methods it will throw a NullPointerException if you call getNumberOfCopies() with a Book that is not in the Map. I explained the reason for that Exception in my previous post.
Marriage Made in Heaven
http://www.youtube.com/user/RohitWaliaWedsSonia
No because when a method is invoked with a parameter then it is a copy of the original reference (in case of Object's). So you're changing the copy of the original reference.Gouri Kumari wrote:Isn't this explanation valid if we declare 'b' as a new Book reference variable. For example: if we add a new method 'work' as below to class TestClass3 and try to invoke it using an object of TestClass3, the key in map won't reflect the change because 'b' defined is local to work method and not the one added to the map.
No because when a method is invoked with a parameter then it is a copy of the original reference (in case of Object's). So you're changing the copy of the original reference.
b = new Book(); // The b reference is changed to point to a different Book. However because the BookStore got a copy of the original reference, that one still points at the other book.
Gouri Kumari wrote:I think you have got me wrong here. I am not invoking a method by passing a copy of reference variable from main method.
Any method works this way. Any reference variable from a parameter is a copy of the original one.Gouri Kumari wrote:Is it like map implementation works differently, ie once a copy of reference is added to a map, any further changes in the original reference will not be reflected in the map.
"Any fool can write code that a computer can understand. Good programmers write code that humans can understand." --- Martin Fowler
Please correct my English.
3. Next, a new Book object is created. Note that its hashcode will be different from the previously created book object. But as per equals() method of Book, they are equal because their isbn are same. When you try to use the new Book object to find the value, map will not find anything because of a different hashcode. So map.get() will return null.[what difference does this make if the newly created Book object isn't even placed in BookStore. Even if the newly created Book object has ISBN if 112, it seems that map.get() will return null since it wasn't placed in BookStore]
Quote from K&B book: If you want objects of your class to be used as keys for a hashtable(or as elements in any data structure that uses equivalency for searching for or retrieving an object) then you must override equlas() so that two different instances can be considered equal. When you want to fetch an object(or for a hash table , retireve the associated value for that object), you have to give the collection a reference to an object that the collection compares to the objects it holds in the collection. As long as the object(stored in the collection) you are trying to search for has the same hashcode as the object you are searching for, then the object will be found.
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime. |