Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/289.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# NET字典解决冲突的能力如何?_C#_.net_Dictionary_Hashcode_Hash Collision - Fatal编程技术网

C# NET字典解决冲突的能力如何?

C# NET字典解决冲突的能力如何?,c#,.net,dictionary,hashcode,hash-collision,C#,.net,Dictionary,Hashcode,Hash Collision,我对需要为表设置关键帧的自定义对象有问题。我需要生成一个唯一的数字键。我有碰撞问题,我想知道我是否可以利用字典来帮助我。假设我有这样一个对象: class Thingy { public string Foo; public string Bar; public string Others; } 等等,还有更多的领域。假设Foo和Bar是我的关键字段-如果它们在两个thingy之间相等,那么这两个对象应该被视为相等(一个对象可能表示对另一个对象的更新,而其他字段正在更新

我对需要为表设置关键帧的自定义对象有问题。我需要生成一个唯一的数字键。我有碰撞问题,我想知道我是否可以利用字典来帮助我。假设我有这样一个对象:

class Thingy
{
    public string Foo;
    public string Bar;
    public string Others;
}
等等,还有更多的领域。假设Foo和Bar是我的关键字段-如果它们在两个thingy之间相等,那么这两个对象应该被视为相等(一个对象可能表示对另一个对象的更新,而其他字段正在更新)。因此我有以下几点:

public override bool Equals(object obj)
{
    Thingy thing = (Thingy)obj; // yes I do type check first
    return (this.Foo == thing.Foo && this.Bar == thing.Bar);
}

public override int GetHashCode()
{
    return (this.Foo + this.Bar).GetHashCode(); // using default string impl
}
所以这在很大程度上是可行的,但是很少有两个实际上不同的东西有相同的哈希代码

我的问题是:我能用一个字典
把我的东西放进去,然后用字典里的顺序值作为我的实际键吗?我想知道,当检测到一个罕见的哈希代码冲突时,字典是否会调用我的Equals方法,确定对象实际上是不同的,并以不同的方式存储它们。我想象,当查找它时,它会看到一个用于该散列的bucket,并搜索正确的东西,再次使用Equals进行比较


字典就是这种情况,还是它只解决哈希代码不同但(哈希%size)相同的冲突?如果这不起作用,会发生什么?

哈希冲突只会影响性能,而不会影响完整性


一个简单的测试是将GetHashCode()更改为只返回1;。您会注意到,字典仍能正常运行,但对于任何合理的数据集,它的性能都会非常差。

哈希冲突主要影响性能,而不是正确性。只要
Equals()
的行为正确

Dictionary
使用哈希代码将项目组织到单独的“bucket”中。如果有太多项共享同一哈希代码,则可能会遇到性能问题。但是,只要
Equals()
能够正确区分实例,就应该得到正确的结果


散列码可能导致问题的地方是可变对象。如果您的
Thingy
类允许
Foo
Bar
更改字典中的某个项目,则在随后的访问尝试中可能找不到它。这是因为现在生成的哈希代码与用于在字典中存储值的哈希代码不同。

GetHashCode是为在哈希表中使用而设计的,在哈希表中,冲突需要最小化,但不能消除。如果需要生成真正唯一的键,GetHashCode是一个合理的起点(没有guid那么长),但需要将键作为对象的一部分存储,并单独维护已使用键的列表


虽然您可能能够从字典的内部检索到看起来可用的内容,但它可能无法可靠地工作-例如,如果您添加的项多于最初分配给字典处理的项,底层数据结构将被重建,单个项目可能会出现在字典的完全不同的部分。

任何字典都是如此。所有字典类型都采用常量键。对于可变对象,您通常希望保留base object.Equals()方法,因为它返回引用相等。通常需要==重载来测试值的相等性。因此,如果不使用默认对象.Equals(),则可以将可变对象用作字典键,而不会产生副作用。通常不建议在非不变类型中重写运算符==。MSDN文档实际上讨论了您可能希望覆盖
Object.Equals()
=
运算符的情况。我以前没读过那篇文章。了解正确的语义和最佳实践总是很好的。谢谢实际上,我使用字典的意思是,我将对象存储为dict的键,然后存储一个新的最高int作为值,并使用该值作为表的键。所以dict中的值是连续的,如果我查找一个对象,我会得到表的唯一数字键。因此,内部字典结构是不相关的。因此,有效地使用字典向对象添加一个附加属性——如果使用可以控制的自定义对象,这不是最有效的方法。