我有,爲什麼我得到的輸出作爲第二線的原因掙扎:運行下面的代碼時,在HashMap的「2號線空」:爲什麼用HashMap中的鍵檢索這些值?
import java.util.*;
class Dog {
public Dog(String n) {name = n;}
public String name;
public boolean equals(Object o) {
if((o instanceof Dog) && (((Dog)o).name == name)) {
return true;
}
else {return false;}
}
public int hashCode() {return name.length();}
}
public class HelloWorld{
public static void main(String []args){
Map<Object, Object> m = new HashMap<Object, Object>();
Dog d1 = new Dog("clover");
m.put(d1, "Dog key");
System.out.println("Line1: " + m.get(d1));
d1.name = "magnolia";
System.out.println("Line2: " + m.get(d1));
d1.name = "clover";
System.out.println("Line3: " + m.get(new Dog("clover")));
d1.name = "arthur";
System.out.println("Line4: " + m.get(new Dog("clover")));
}
}
顯示輸出爲:
一號線:狗鍵
線路2:空
3號線:狗鍵
線路4:空
是的,我知道修改實例變量名稱反過來會影響狗的實例的哈希碼,因爲我計算哈希碼的方式。但是,我正在使用與密鑰相同的實例!那麼,爲什麼get()方法不能找到相應的值呢?似乎一旦一對被推入HashMap中,密鑰將永久硬編碼!這是它應該如何工作,這意味着,一旦散列碼已經被確定爲一個值之前,將對放置在HashMap中,散列碼永遠不會再被修改?
是的,當然。如果您嘗試使用修改的哈希碼獲取(),那麼HashMap應該如何知道匹配的內容? –
您應該使用'equals'而不是'=='比較字符串(例如'Dog.name')。另外,你期望與你當前的'hashCode'實現有很多衝突。你可以使用'return name.hashCode()'來代替。 –
Oliver是正確的。您重寫的'hashcode'方法會根據Dog的名稱字段返回值。由於'clover'返回6,'magnolia'返回8,所以當你調用get()時,由於前一個條目的哈希碼是6,與第二次(8)通過的哈希碼不同, ,它將無法找到相應的條目並返回null – Arkantos