使用可变对象作为Hashmap键是一种不好的做法吗?当您尝试使用已被足够修改以更改其哈希码的键从哈希图检索值时,会发生什么情况?

例如,给定

class Key
{
    int a; //mutable field
    int b; //mutable field

    public int hashcode()
        return foo(a, b);
    // setters setA and setB omitted for brevity
}


带代码

HashMap<Key, Value> map = new HashMap<Key, Value>();

Key key1 = new Key(0, 0);
map.put(key1, value1); // value1 is an instance of Value

key1.setA(5);
key1.setB(10);


现在调用map.get(key1)会发生什么?这是安全还是可取的?还是行为取决于语言?

最佳答案

许多受人尊敬的开发人员(例如Brian Goetz和Josh Bloch)都指出:


如果对象的hashCode()值可以根据其状态更改,那么我们
在基于散列的对象中将此类对象用作键时必须小心
集合,以确保我们不允许它们的状态在
它们被用作哈希键。所有基于散列的集合均假定
对象的哈希值在用作对象时不会发生变化
键入集合。如果密钥的哈希码在更改时发生变化
在一个集合中,带来一些无法预料和令人困惑的后果
可以跟随。在实践中,这通常不是问题-并非如此
在列表中使用可变的对象(如列表)作为键的常见做法
HashMap。

关于hash - 可变的hashmap键是危险的做法吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57723337/

10-16 02:56