package always.confusing;
import java.util.HashMap;
import java.util.Map;
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 QustionToaAsk {
public static void main(String[] args) {
// TODO Auto-generated method stub
Map<Object, Object> m = new HashMap<Object, Object>();
Dog d1 = new Dog("clover");
m.put(d1, "Dog key");
System.out.println("**" + m.get(new Dog("clover")));
d1.name = "magnolia";
System.out.println("state after magnolia");
System.out.println(m.get(new Dog("magnolia")));
System.out.println(m.get(d1)); // #1
System.out.println("**" + m.get(new Dog("clover")));///????????
System.out.println("size:" + m.size());
d1.name = "clover";
System.out.println("\nstate after clover");
System.out.println(m.get(new Dog("clover"))); // #2
System.out.println(m.get(d1));
System.out.println("size:" + m.size());
d1.name = "arthur";
System.out.println("\nstate after arthur");
System.out.println(m.get(new Dog("arthur")));
System.out.println(m.get(d1));
System.out.println("size:" + m.size());
}
}
输出:
**Dog key
Jade 兰花后的状态
null
null
**null
size:1
三叶草之后的状态
Dog key
Dog key
size:1
亚瑟之后的状态
Dog key
Dog key
size:1
为什么第一组打印无法获取具有三叶草和木兰内容的 Dog 对象 但在其他两组中它是否符合预期?
即为什么在尝试更改为“magnolia”后,为什么下一个 get()(仍然使用正确的对象,即 get(new Dog("clover"))))无法获取值“Dog key”?更改为 equals.. 后输出仍然相同 –
//忽略
最佳答案
您需要了解 HashMap 的工作原理。
当您将一个键放入包含 N 个存储桶的 HashMap 中时,将使用该键的 hashCode 来查找适当的存储桶。然后使用 equals() 将存储桶中包含的每个键与添加的键进行比较,以了解该键是否已在映射中。
类似地,当获取某个键的值时,首先使用 hashCode() 查找合适的存储桶,然后使用 equals() 将该存储桶中的每个键与传递给 get() 的键进行比较。
在使用 HashMap 时,您正在做两件不应该做的事情:
- 将 key 存储在 map 中后对其进行修改。这会修改其 hashCode,并导致无法在适当的存储桶中搜索该键。有点像你把所有红色硬币放在一个红色抽屉里,然后将其中一把 key 重新漆成蓝色。显然,如果您随后搜索蓝色硬币,您将在蓝色抽屉中搜索它们,而不是在存储硬币的红色抽屉中搜索它们,因为它最初是红色的。
- 使用使许多键具有相同值的算法来实现 hashCode()。 “clover”和“arthur”就是这种情况,它们具有相同的长度,因此在您的实现中具有相同的 hashCode() 。另一方面,“magnolia”没有相同的 hashCode()。
鉴于上述内容,您应该能够理解为什么您的代码会这样工作。只要在纸上画出每个操作发生的情况,您就会明白。
关于java - 修改HashMap key之一,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24149035/