I got you. but after carefully observing your code 15 mins. Its not that easy for me.
Now into details,
1. Dog d = new Dog("clover"); This line looks simple; but key to whole explanation;
here we are creating Dog in heap with state name = clover;
2. m.put(d, "This is clover dog"); Here d.hashCode() calulated and it will be placed in corresponding bucket.
hashCode() = 6 (length of string). So its placed in 6th bucket.
Here what need to understood is Object will only be there in Heap. just reference will be put in map.
3. System.out.println(m.get(d));// line 1
Here to find which bucket d belongs, it will calculate hashCode on it. Here d still points to "clover"; so hashCode = 6;
Now we are in 6th bucket; it will iterate on elements in bucket 6 and takes fisrt object reference.
*** here both the references we passed are same. so no need to call equals.
Thats why we got the value "This is clover Dog"
4. d.name = "magnolia";
// here the object state on heap changed to "magnolia". System.out.println("\n===========");
5.System.out.println(m.get(d));// line 2 // hashCode(d) --> 8(length of "magnolia".) but it founds nothing in the 8th bucket return null. ***Remember, we have only one element in 6th element.
6. d.name = "argume"; Again changing the state of object; **** Here you are placing d reference in pool. useful in step 7
7. System.out.println(m.get(new Dog("argume"))); // line 3
// This is very complex to understand; prepare for this;
you are now creating another Dog in heap with state "argume"; hashCode returns 6;
so in 6th bucket it will iterate and fetches the first element here map element's d reference and new Dog("argume")'s references are differnt.
So executes equals() method. // your equals definition is very poor. not efficient. // you are comparing both dog object's references. not contents. Here you need String's pool concept to understand why reference( Map element's d.name ) == reference(new Dog("argume").name)
reference( Map element's d.name ) >>> 1. Map has only reference to Dog Object; its state changed in 6th step as d.name = "argume";
"argume" will be created in heap and reference placed in pool. reference(new Dog("argume").name) 2. second time when you refer "argume" it will check in pool and gives that reference[ no new string "argume" created here]
So, the point is if we are using the same reference variable as the get() method's argument, it will not check for the equality, isn't it? Hmm... I think I have to review again the String pool concept.