【发布时间】:2013-02-28 11:43:41
【问题描述】:
我了解不建议使用“可变”对象(其 GetHashCode() 方法在用作Dictionary 中的键时可以返回不同结果的对象)。
以下是我对实现为哈希表的字典如何工作的理解:
当我添加新密钥时,例如dict.Add(m1, "initially here was m1 object");,dict 使用GetHashCode() 方法计算m1 的哈希码。然后它做一些内部计算,最后把这个对象放到它内部数组的某个位置。
当我使用键索引获取值时,例如dict[m1],dict 再次计算哈希码。然后它进行一些内部计算,它给了我一个位于其内部数组内部计算位置的对象。
但我认为有一个我找不到的错误。
假设我有这个代码:
class MutableObject
{
Int32 m_value;
public MutableObject(Int32 value)
{
m_value = value;
}
public void Mutate(Int32 value)
{
m_value = value;
}
public override int GetHashCode()
{
return m_value;
}
}
static void Main(string[] args)
{
MutableObject m1 = new MutableObject(1);
MutableObject m2 = new MutableObject(2);
var dict = new Dictionary<MutableObject, String>();
dict.Add(m1, "initially here was m1 object");
dict.Add(m2, "initially here was m2 object");
Console.WriteLine("Before mutation:");
Console.WriteLine("dict[m1] = " + dict[m1]);
Console.WriteLine("dict[m2] = " + dict[m2]);
m1.Mutate(2);
m2.Mutate(1);
Console.WriteLine("After mutation:");
Console.WriteLine("dict[m1] = " + dict[m1]);
Console.WriteLine("dict[m2] = " + dict[m2]);
Console.ReadKey(true);
}
当我调用 Mutate 方法时,键被交换。所以我认为它会给出交换的结果。但实际上这一行:Console.WriteLine("dict[m1] = " + dict[m1]); 抛出 KeyNotFoundException,我不明白为什么。显然我在这里遗漏了一些东西......
【问题讨论】:
-
只有 40 亿个可能的哈希码。假设运气不好,您在同一个哈希表中有两个不相等的对象,具有相同的哈希码。 字典如何区分它们?当您回答这个问题时,您就会明白为什么您的程序会为您提供您所看到的结果。
-
我知道 hasttable 可以实现链接,或者开放寻址算法,例如,对抗碰撞。所以当我调用
dict[m1]他得到哈希码,交换后等于2,然后......他做了什么?他试图弄清楚,具有此哈希码的哪个对象是正确的,他应该返回哪个对象...... -
你在 1 Elm Street 买房子,然后在 2 Elm Street 买房子并搬到那里。您将第二所房子的地址标志更改为 1 Elm Street。发往 1 Elm Street 的邮件在哪里投递?
-
很好的模拟,谢谢:)
标签: c# .net data-structures hashtable