更改用作Map键的对象

时间:2012-04-14 10:58:02

标签: java map

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

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

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

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

编辑:认为密钥不是字符串而是可变对象,如下面的文章中所述。

5 个答案:

答案 0 :(得分:5)

引自“Map”界面JavaDoc:

  

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

你根本不应该改变键(以改变其“hashCode”/“equals”的方式)。如果你尝试的话,你肯定会进行非常漫长而糟糕的调试。

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

答案 1 :(得分:1)

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

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

答案 2 :(得分:1)

通过调用v.setK(),您不会更改HashMap中的键。所以你的V对象中只会有错误的信息。

答案 3 :(得分:1)

此问题的标题具有误导性 - 您不会更改地图密钥,例如变更用作地图密钥的对象。当您说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);

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

答案 4 :(得分:1)

V v = new V();
v.setK("a");
HashMap<K,V> map = new HashMap<K,V>();
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");

从地图中获取此对象
V v = new V();
v.setK("a");
map.get(v.getK());

PS:我没有尝试过这个