我一直在用c ++和java编写我的生活,但在C#上,我觉得这是一个完全不同的动物。
如果在c#中的Dictionary容器中发生哈希冲突,它会怎么做?或者它甚至检测到碰撞?
如果在SDL中的类似容器中发生冲突,有些会将关键值部分链接数据链接到键值部分,如链接列表,或者有些人会尝试查找不同的哈希方法。
[更新10:56 A.M. 2010年6月4日]
我正在尝试为每个用户制作一个计数器。并且设置用户#没有定义,它可以增加或减少。我期待数据的大小超过1000.
所以,我想:
Hashmap是我的解决方案,似乎Dictionary与c#...
中的hashmap类似答案 0 :(得分:40)
哈希冲突由Dictionary<>
正确处理 - 只要对象正确实现GetHashCode()
和Equals()
,就会返回相应的实例字典。
首先,您不应对Dictionary<>
内部如何工作做出任何假设 - 这是一个可能随时间变化的实现细节。说完了......
您应该关注的是,您用于密钥的类型是否正确实现GetHashCode()
和Equals()
。基本规则是GetHashCode()
必须返回对象生命周期的相同值,当两个实例表示同一个对象时,Equals()
必须返回true。除非您覆盖它,否则Equals()
使用引用相等 - 这意味着只有两个对象实际上是同一个实例才返回true。您可以覆盖Equals()
的工作方式,但是您必须确保两个“相等”的对象也生成相同的哈希码。
从性能角度来看,您可能还希望提供GetHashCode()
的实现,它可以生成良好的值扩展,以减少哈希码冲突的频率。哈希码冲突的主要缺点,就是它在性能方面将字典缩减为列表。每当两个不同的对象实例产生相同的哈希码时,它们就存储在字典的同一内部桶中。结果是,必须执行线性扫描,在每个实例上调用Equals()
,直到找到匹配为止。
答案 1 :(得分:13)
根据this article at MSDN,如果发生哈希冲突,Dictionary
类会将存储桶转换为链表。另一方面,较旧的HashTable
类使用rehashing。
答案 2 :(得分:6)
我提供了一个替代的面向代码的答案,它演示了当添加了两个具有不同键的项但键生成相同的哈希码时,Dictionary将表现出无异常和功能正确的行为。
在.Net 4.6上,字符串“699391”和“1241308”产生相同的哈希码。以下代码会发生什么?
myDictionary.Add( "699391", "abc" );
myDictionary.Add( "1241308", "def" );
以下代码演示了.Net Dictionary接受导致哈希冲突的不同密钥。抛出没有异常,字典键查找返回预期的对象。
var hashes = new Dictionary<int, string>();
var collisions = new List<string>();
for (int i = 0; ; ++i)
{
string st = i.ToString();
int hash = st.GetHashCode();
if (hashes.TryGetValue( hash, out string collision ))
{
// On .Net 4.6 we find "699391" and "1241308".
collisions.Add( collision );
collisions.Add( st );
break;
}
else
hashes.Add( hash, st );
}
Debug.Assert( collisions[0] != collisions[1], "Check we have produced two different strings" );
Debug.Assert( collisions[0].GetHashCode() == collisions[1].GetHashCode(), "Prove we have different strings producing the same hashcode" );
var newDictionary = new Dictionary<string, string>();
newDictionary.Add( collisions[0], "abc" );
newDictionary.Add( collisions[1], "def" );
Console.Write( "If we get here without an exception being thrown, it demonstrates a dictionary accepts multiple items with different keys that produce the same hash value." );
Debug.Assert( newDictionary[collisions[0]] == "abc" );
Debug.Assert( newDictionary[collisions[1]] == "def" );
答案 3 :(得分:2)
点击此链接可获得一个很好的解释:An Extensive Examination of Data Structures Using C# 2.0
基本上,.NET泛型字典链接具有相同散列值的项目。