当前位置: 首页 > 编程语言 > C#

Dictionary键发生哈希冲突时会发生什么?Share

时间:2023-04-10 21:22:12 C#

当字典键中出现哈希冲突时会发生什么?我一直在用C++和Java编程,但在C#上,我觉得它是完全不同的动物。c#中Dictionary容器发生hash冲突怎么办?甚至检测碰撞?在像SDL中的容器中发生冲突的情况下,有些会使键值部分将数据链接到键值部分,如链表,或者有些会尝试找到不同的哈希方法。[更新于2010年6月4日上午10:56]我想为每个用户制作一个计数器。而setuser#是没有定义的,可以增减。我期望数据的大小超过1000。所以,我想:Hashmap是我的解决方案,似乎Dictionary类似于c#中的hashmap...哈希冲突由Dictionary正确处理-只要对象正确实现GetHashCode()和Equals(),相应的实例。首先,您不应该对Dictionary的内部工作方式做出任何假设——它是一个可能随时间变化的实现细节。话虽如此……您应该关心的是您用于密钥的类型是否正确实现了GetHashCode()和Equals()。基本规则是GetHashCode()必须在对象的生命周期内返回相同的值,而Equals()必须在两个实例代表同一个对象时返回true。除非您覆盖它,否则Equals()使用引用相等性-这意味着它仅在两个对象实际上是同一实例时才返回true。您可以覆盖Equals()的工作方式,但是您必须确保两个“相等”的对象也生成相同的哈希码。从性能的角度来看,您可能还想提供GetHashCode()的实现,它可以生成良好的价值传播以减少哈希码冲突的频率。哈希码冲突的主要缺点是它在性能方面将字典简化为列表。每当两个不同的对象实例产生相同的哈希码时,它们都存储在字典的同一个内部桶中。因此,必须执行线性扫描,对每个实例调用Equals()直到找到匹配项。根据MSDN上的这篇文章,Dictionary类在哈希冲突的情况下将桶转换为链表。另一方面,较旧的HashTable类使用重新散列。我提供了一个替代的面向代码的答案,该答案表明当添加具有不同键的两个项目但键生成相同的哈希码时,Dictionary将表现出无异常和功能正确的行为。在.Net4.6上,字符串“699391”和“1241308”产生相同的哈希码。以下代码会发生什么?myDictionary.Add("699391","abc");myDictionary.Add("1241308","def");以下代码演示了.NetDictionary接受会导致散列冲突的不同键。没有抛出异常,字典键查找返回预期的对象。varhashes=newDictionary();varcollisions=newList();for(inti=0;;++i){字符串st=i.ToString();inthash=st.GetHashCode();if(hashes.TryGetValue(hash,outstringcollision)){//在.Net4.6上,我们找到“699391”和“1241308”。碰撞。添加(碰撞);碰撞。添加(st);休息;}elsehashes.Add(hash,st);}Debug.Assert(collisions[0]!=collisions[1],"检查我们产生了两个不同的字符串");Debug.Assert(collisions[0].GetHashCode()==collisions[1].GetHashCode(),"证明我们有不同的字符串产生相同的哈希码");varnewDictionary=newDictionary();newDictionary.Add(碰撞[0],"abc");newDictionary.Add(碰撞[1],"def");Console.Write("如果我们到达这里时没有抛出异常,则表明字典接受具有不同键的多个项目,这些项目产生相同的哈希值。");Debug.Assert(newDictionary[collisions[0]]=="abc");Debug.Assert(newDictionary[collis离子[1]]=="def");查看此链接以获得很好的解释:使用C#2.0对数据结构进行广泛检查基本上,.NETgenerics字典链接具有与上述相同哈希值的项目这是C#学习教程:当字典键中存在哈希冲突时会发生什么?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: