Reputation: 187
I really don't understand from the below code how the get() methods, set() methods and toString() are called. Could someone explain me ?
The whole point here is after seeing the output I don't understand how the tostring method has been called. I don't see anything explicitly being called.
public class MyDuplicateKeyEx {
public static void main(String a[]){
HashMap<Price, String> hm = new HashMap<Price, String>();
hm.put(new Price("Banana", 20), "Banana");
hm.put(new Price("Orange", 30), "Orange");
printMap(hm);
Price key = new Price("Banana", 20);
System.out.println("Adding duplicate key...");
hm.put(key, "Grape");
System.out.println("After adding dulicate key:");
printMap(hm);
}
public static void printMap(HashMap<Price, String> map){
Set<Price> keys = map.keySet();
for(Price p:keys){
System.out.println(p+"==>"+map.get(p));
}
}
}
class Price{
private String item;
private int price;
public Price(String itm, int pr){
this.item = itm;
this.price = pr;
}
public int hashCode(){
int hashcode = 0;
hashcode = price*20;
hashcode += item.hashCode();
return hashcode;
}
public boolean equals(Object obj){
if (obj instanceof Price) {
Price pp = (Price) obj;
return (pp.item.equals(this.item) && pp.price == this.price);
} else {
return false;
}
}
public String getItem() {
return item;
}
public void setItem(String item) {
this.item = item;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public String toString(){
return "item: "+item+" price: "+price;
}
}
Output:
item: Apple price: 40==>Apple
item: Orange price: 30==>Orange
item: Banana price: 20==>Banana
Adding duplicate key...
After adding dulicate key:
item: Apple price: 40==>Apple
item: Orange price: 30==>Orange
item: Banana price: 20==>Grape
Thanks !!
Upvotes: 2
Views: 95
Reputation: 270980
Of course there is no explicit toString
! Java does this implicitly for you! You should thank him, ya know.
The magic lies behind this code:
p+"==>"+map.get(p)
Here, p
is a Price
and map.get(p)
is a String
. So the above is basically adding a price to a string, then add another string to the result.
When Java wants to add any object to a string, it calls that object's toString
to convert that object to String
first. Otherwise, how can a price be added to a string, right?
Tip:
Never use objects which hash code can change as keys of a hash map. I have actually seen a person who was very extreme and he implemented the hashCode
method with Math.random()
! Here's the post: Could not understand the output And asked why can a hash map store things with the same hash code.
So to avoid that confusion, please don't use mutable objects as keys. Just remove those setters and you'll be fine.
Upvotes: 0
Reputation: 12246
You are right, there is no explicit call to toString
. But under the hood, that is what Java is doing. When seeing p+"==>"+map.get(p)
, Java is doing p.toString()+"==>"+map.get(p).toString()
. That is why you can concatenate strings and objects without problems.
Additionally, a better way of iterating through the key/values of a Map is:
public static void printMap(HashMap<Price, String> map) {
for (Map.Entry<Price, String> entry : map.entrySet()) {
System.out.println(entry.getKey() + "==>" + entry.getValue())
}
}
When using a HashMap with user-defined objects as keys, you must be very careful that you do never modify the fields used to compute the hashCode
if they are present in the map. This is why you'll often see that final fields should be used to compute it. With a large program, this avoids lots of unnecessary mistakes.
Upvotes: 2