可变的hashmap键是一种危险的做法吗? [英] Are mutable hashmap keys a dangerous practice?
问题描述
使用可变对象作为Hashmap键是不好的做法吗?如果您尝试使用已修改足以更改其哈希码的密钥从Hashmap中检索值,会发生什么情况?
例如,给定 class Key
{
int a; //可变字段
int b; //可变字段
public int hashcode()
return foo(a,b);
}
包含代码
HashMap< Key,Value> map = new HashMap< Key,Value>();
钥匙1 =新钥匙(0,0);
map.put(key1,value1);
key1.setA(5);
key1.setB(10);
如果我们现在调用 map.get(key1)
?这是安全还是可取的?或者是依赖于语言的行为?
许多备受尊敬的开发人员已经注意到这一点,如Brian Goetz和Josh Bloch那么:
lockquote
如果一个对象的hashCode()值可以根据它的状态改变,那么当使用这样的方法时,我们
必须小心对象作为基于散列的
集合中的键,以确保当
被用作散列键时,我们不允许它们的状态发生更改。所有基于散列的集合都假定
,在集合中它被用作
键时,对象的散列值不会更改。如果密钥的哈希码在
在集合中时发生更改,则可能会出现一些不可预知和令人困惑的后果
。这在实际中通常不是问题 - 使用像List这样的可变对象作为
HashMap中的键是不常见的做法。
Is it bad practice to use mutable objects as Hashmap keys? What happens when you try to retrieve a value from a Hashmap using a key that has been modified enough to change its hashcode?
For example, given
class Key
{
int a; //mutable field
int b; //mutable field
public int hashcode()
return foo(a, b);
}
with code
HashMap<Key, Value> map = new HashMap<Key, Value>();
Key key1 = new Key(0, 0);
map.put(key1, value1);
key1.setA(5);
key1.setB(10);
What happens if we now call map.get(key1)
? Is this safe or advisable? Or is the behavior dependent on the language?
It has been noted by many well respected developers such as Brian Goetz and Josh Bloch that :
If an object’s hashCode() value can change based on its state, then we must be careful when using such objects as keys in hash-based collections to ensure that we don’t allow their state to change when they are being used as hash keys. All hash-based collections assume that an object’s hash value does not change while it is in use as a key in the collection. If a key’s hash code were to change while it was in a collection, some unpredictable and confusing consequences could follow. This is usually not a problem in practice — it is not common practice to use a mutable object like a List as a key in a HashMap.
这篇关于可变的hashmap键是一种危险的做法吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!