更改用作Map键的对象

设V是一个具有名为K的单个属性及其getter和setter的类。

如果我这样做会发生什么:

V v = new V(); v.setK("a"); HashMap map = new HashMap(); map.put(v.getk(),v); v.setK("b"); 

据我所知,这应该会导致某种问题,因为地图键应该是不变的。 这会发生什么?

编辑:考虑键不是字符串而是可变对象,如下面的文章中所述。

从“Map”界面JavaDoc引用:

如果将可变对象用作映射键,则必须非常小心。 如果在对象是地图中的键的同时以影响等于比较的方式更改对象的值,则不指定映射的行为。

你根本不应该改变键(以改变它们的“hashCode”/“equals”的方式)。 如果你尝试,你肯定会有很长很糟糕的调试。

这就像你在图书馆交换书籍。 索引变得不可靠。 你搜索“Bradbury”,但找到“Simak”。

如果您尝试使用v.getk()查找地图,则无法找到条目,因为您已在v上更改了getter的值返回值。

或者换句话说,地图不会神奇地与v对象发生的事情保持同步 – 它使用(并继续使用) put()给出的值。

通过调用v.setK(),您不会更改HashMap中的键。 因此,您的V对象中只会包含错误的信息。

 V v = new V(); v.setK("a"); HashMap map = new HashMap(); map.put(v.getk(),v); //Nothing will change in the hashmap with this step v.setK("b"); 

但问题是从地图中获取对象V. 如果调用map.get(v.getk()),则将获得null,因为映射中的值与对象“a”映射。 但是,由于这个字符串“a”是inter,你总是可以通过map.get("a");从map中获取这个对象map.get("a"); 要么

 V v = new V(); v.setK("a"); map.get(v.getK()); 

PS:我没有试过这个

这个问题的标题是误导性的 – 你没有改变地图键,就像改变用作地图键的对象一样 。 当您说map.put(x, y) ,您正在创建一个聚合两个独立值的映射条目 。 地图不能看到密钥的来源,它只是两个对象。 所以,你已经创建了一个地图条目("a", v) ,之后你只是改变了v的状态 – 这无法影响地图条目的关键字“a”。 另一方面,如果你有自己制作的物体K,就像

 public class K { private String s; public K(String s) { this.s = s; } public void setS(String s) { this.s = s; } public boolean equals(Object o) { return ((K)o).s.equals(this.s); } public int hashCode() { return s.hashCode(); } 

}

现在你做

 final K k = new K("a"); map.put(k, v); k.setS("b"); map.get(k); 

然后你会遇到问题 – 你改变了用作地图键的对象