据我(认为)所知,Dictionary
是作为散列表实现的,其中散列码用于标识存储桶,然后在存储桶中搜索键。
在我看来,这意味着对象的哈希码在我的程序单次运行期间保持稳定(粗略地说)。
现在,这里
http://msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx
我读了
“哈希码用于在基于哈希表的集合中高效插入和查找。哈希码不是永久值。因此: [...] 不要使用哈希码作为键从键控集合中检索对象。”
谁能给我解释一下这是什么意思?
最佳答案
当文档谈到“键控集合”时,它们与字典的含义不同。要深入了解它的实际含义,请注意实际上有一个 KeyedCollection
。基类:http://msdn.microsoft.com/en-us/library/ms132438%28v=vs.110%29.aspx
关键段落是这样的:
Unlike dictionaries, an element of
KeyedCollection<TKey, TItem>
is not a key/value pair; instead, the entire element is the value and the key is embedded within the value. For example, an element of a collection derived fromKeyedCollection<String,String>
(KeyedCollection(Of String, String)
in Visual Basic) might be "John Doe Jr." where the value is "John Doe Jr." and the key is "Doe"; or a collection of employee records containing integer keys could be derived fromKeyedCollection<int,Employee>
. The abstractGetKeyForItem
method extracts the key from the element.
因此,键控集合是对象的集合以及从每个对象中提取键的方法。从概念上讲,这类似于数据库中的表,您可以在其中定义一个主键,它是整个记录的一个子集。
所以考虑到这一点,答案就变得相对清楚了。正如其他人所说,哈希码相等并不意味着对象相等。但是键控集合中的键——就像数据库表中的主键——应该唯一地标识确切的对象。因此哈希冲突的可能性使它们不适合用于此目的。
此外,即使在 Dictionary
中,使用对象作为键和使用相同对象的哈希码作为键之间有一个重要的区别。如果两个对象发生哈希冲突但不相等,则 Dictionary
仍会将它们存储为两个单独的 key 。这就是为什么重写 GetHashCode
只返回 1 总是有效的(虽然显然不利于性能)。作为演示:
var dict = new Dictionary<MyClass, string>();
var hashDict = new Dictionary<int, string>();
dict[myObj1] = "One";
hashDict[myObj1.GetHashCode()] = "One";
dict[myObj2] = "Two";
hashDict[myObj2.GetHashCode()] = "Two";
Console.Out.WriteLine(dict[myObj1]); //Outputs "One"
Console.Out.WriteLine(hashDict[myObj1.GetHashCode()]); //Outputs "Two"
(myObj1
和 myObj2
是 MyClass
的实例,它们具有相同的哈希码但不比较相等)
关于c# - 哈希码作为键控集合中的键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24026104/