Let V be a class with a single attribute named K and its getter and setters.
What\'s supposed to happen if I do:
V v = new V();
v.setK(\"a\");
HashMa
Quote from "Map" interface JavaDoc:
Great care must be exercised if mutable objects are used as map keys. The behavior of a map is not specified if the value of an object is changed in a manner that affects equals comparisons while the object is a key in the map.
You simply shouldn't mutate keys (in the way which changes their "hashCode"/"equals"). You will definitely have very long and awful debugging if you try.
It's like you swap books in the library. Index became unreliable. You search for "Bradbury", but find "Simak".
If you were trying to look up the map using v.getk()
it wouldn't find an entry, because you've changed the value return by the getter on v.
Or in other words, the map isn't magically kept in sync with what happens to your v object - it uses (and keeps using) the value given to it in the put()
.
The title of this question is misleading -- you are not changing the map key, as in mutating the object used as map key. When you say map.put(x, y)
, you are creating a map entry that aggregates two independent values: a key and a value. Where the key originates from is not seen by the map, it's just two objects. So, you have created a map entry ("a", v)
and after that you just changed the state of v -- there is no way this could have influenced the map entry's key "a". If, on the other hand, you had an object K of your own making, like
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(); }
}
and now you do
final K k = new K("a");
map.put(k, v);
k.setS("b");
map.get(k);
then you would face the problem -- you mutated the object used as the map key.
By calling v.setK(), you aren't changing the key in the HashMap. So you will simply have wrong information in your V object.
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");
but the problem will be while fetching the object V from map. If you call map.get(v.getk()), you will get null because the value in the map is mapped with object "a". However, since this String "a" is inter you can always fetch this object from map by map.get("a");
or
V v = new V();
v.setK("a");
map.get(v.getK());
PS: I have not tried to run this