Reputation: 623
Consider ther following code :
public class CarEqualsTestAgain {
String model;
public CarEqualsTestAgain(String x) {
this.model=x;
}
@Override
public int hashCode(){ //bad hashcode
System.out.println("__hash__");
return 1;
}
@Override
public boolean equals(Object o){
System.out.println("In equals");
if((o instanceof CarEqualsTestAgain) && ((CarEqualsTestAgain)o).model==this.model){
return true;
}
else
return false;
}
public static void main(String[] args) {
Map map=new HashMap();
CarEqualsTestAgain car1=new CarEqualsTestAgain("8");
map.put(car1, "Red");
System.out.println("Key1 : "+map.get(car1)); //Line 1
CarEqualsTestAgain car2=new CarEqualsTestAgain("8");
System.out.println("Key2 : "+map.get(car2)); //Line 2
CarEqualsTestAgain car3=car1;
System.out.println("Key3 : "+map.get(car3)); //Line 3
CarEqualsTestAgain car4=new CarEqualsTestAgain("9");
map.put(car4, "Red");
System.out.println("Key4 : "+map.get(car4)); //Line 4
CarEqualsTestAgain car5=new CarEqualsTestAgain("10");
map.put(car5, "Red");
System.out.println("Key5 : "+map.get(car5)); //Line 5
CarEqualsTestAgain car6=new CarEqualsTestAgain("8");
map.put(car6, "Green");
System.out.println("Key6 : "+map.get(car6)); //Line 6
key=(String)map.get(car1);
System.out.println("Key1 : "+key); //Line 7
}
}
Prints output as:
__hash__
__hash__
Key1 : Red
__hash__
In equals
Key2 : Red
__hash__
Key3 : Red
__hash__
In equals
__hash__
Key4 : Red
__hash__
In equals
In equals
__hash__
Key5 : Red
__hash__
In equals
In equals
In equals
__hash__
In equals
In equals
In equals
Key6 : Red
__hash__
In equals
In equals
Key1 : Green
My Question is :
1) When each Object is created JVM calculate its hashcode and put it in bucket or When Hashmap put() method is called then only JVM uses key Object to calculate hashcode ?
2) put() and get() calls both hashcode and equals method. Hence put() method calls overrided equals() correctly depending upon the no. of objects in bucket as seen in output for Line 1,4,5,6. But for get() method it is not the same. For Line 1 get() doesn't call equal(), Line 2 did, Line 3,4,5 didn't call, Line 6 did. Line 7 didn't WHY?
3) equals(Object o) method compares the passed object i.e Object o with all Objects resides in bucket with given hashcode. Then why did it doesn't stop comapring when it found one early. Ex - Say in bucket 1928 car1 car4 car5 resides, so when car6 calls get() which calls equals() then if car6 compares with car1 and found to be equal then it should stop comparing, but instead it compares 3 times. WHY?
Upvotes: 0
Views: 103
Reputation: 1503799
When each Object is created JVM calculate its hashcode and put it in bucket or When Hashmap put() method is called then only JVM uses key Object to calculate hashcode ?
It only calls hashCode()
when it needs to - in this case when you call put()
or get()
.
For Line 1 get() doesn't call equal(), Line 2 did, Line 3,4,5 didn't call, Line 6 did. Line 7 didn't WHY?
You're getting confused by your own diagnostics. This call:
System.out.println("Key1 : "+map.get(car1));
is equivalent to:
Object tmp = map.get(car1);
System.out.println("Key1 : " + tmp);
So the call to equals
occurs before you print Key1
. To make it simpler to understand, you should change your diagnostics to:
System.out.println("Test 1");
CarEqualsTestAgain car1 = new CarEqualsTestAgain("8");
System.out.println("Created car");
map.put(car1, "Red");
System.out.println("Added car to map");
Object tmp = map.get(car1);
System.out.println("Result of get: " + tmp);
That way it's clearer what happens when. In general, both put()
and get()
need to:
hashCode()
on the key you're adding/fetchingequals()
for each match, until either it runs out of matches or finds an equal object3) equals(Object o) method compares the passed object i.e Object o with all Objects resides in bucket with given hashcode. Then why did it doesn't stop comapring when it found one early. Ex - Say in bucket 1928 car1 car4 car5 resides, so when car6 calls get() which calls equals() then if car6 compares with car1 and found to be equal then it should stop comparing, but instead it compares 3 times. WHY?
You're assuming that it compares with car1
first. Hash maps are effectively unordered - there's no guarantee which order candidates with equal hash codes will be compared in. It will stop when it finds a match though. If you change your hash code to be more sensible, it's very likely that it will only need to check one item.
Upvotes: 1