请考虑以下代码:
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
}
}
将输出打印为:
__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
我的问题是:
1)当创建每个Object时,JVM计算其哈希码并将其放入存储桶中或当调用Hashmap put()方法时,只有JVM使用关键Object来计算哈希码?
2)put()和get()调用hashcode和equals方法。因此put()方法调用正确地覆盖了equals(),具体取决于no。铲斗中的物体,如第1,4,5,6行的输出所示。但是对于get()方法,它是不一样的。对于第1行,get()不调用equal(),第2行没有,第3,4,5行没有调用,第6行没有调用。第7行没有为什么?
3)equals(Object o)方法比较传递的对象,即对象o,所有对象都驻留在桶中,并带有给定的哈希码。那么为什么它不能在早期找到它时停止共同制作。 Ex - 在桶1928中说car1 car4 car5驻留,所以当car6调用get()时调用equals()然后如果car6与car1比较并且发现它相等那么它应该停止比较,而是比较3次。为什么?
答案 0 :(得分:1)
当创建每个Object时,JVM计算其哈希码并将其放入存储桶中或当调用Hashmap put()方法时,只有JVM使用关键Object来计算哈希码?
只有在需要时才会调用hashCode()
- 在这种情况下,当您致电put()
或get()
时。
对于第1行,get()不会调用equal(),第2行没有,第3,4,5行没有调用,第6行没有调用。第7行没有为什么?
您对自己的诊断感到困惑。这个电话:
System.out.println("Key1 : "+map.get(car1));
相当于:
Object tmp = map.get(car1);
System.out.println("Key1 : " + tmp);
因此,在打印equals
之前,对Key1
的调用会发生。为了使其更易于理解,您应该将诊断更改为:
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);
这样就更清楚了。通常,put()
和get()
都需要:
hashCode()
equals()
,直到它用完匹配或找到相同的对象3)equals(Object o)方法比较传递的对象,即对象o,所有对象都驻留在桶中,并带有给定的哈希码。那么为什么它在早期发现一个时就不会停止comapring。 Ex - 在桶1928中说car1 car4 car5驻留,所以当car6调用get()时调用equals()然后如果car6与car1比较并且发现它相等那么它应该停止比较,而是比较3次。为什么?
您首先假设它与car1
进行比较。哈希映射实际上是无序的 - 不能保证哪些具有相同哈希码的候选者将被比较。当将在找到匹配时停止。如果您将哈希码更改为更合理,则很可能只需要检查一个项目。