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

使用xor的GetHashCode()问题分享

时间:2023-04-10 12:56:17 C#

使用xor的GetHashCode()问题它)。这是一个简单的例子:classFoo{intm_a;诠释m_b;publicintA{get{返回m_a;}设置{m_a=值;}}publicintB{get{returnm_b;}设置{m_b=值;}}publicFoo(inta,intb){m_a=a;m_b=b;}publicoverrideintGetHashCode(){returnA^B;}publicoverrideboolEquals(objectobj){returnthis.GetHashCode()==obj.GetHashCode();我的想法是,我想根据属性A和B的值将Foo的一个实例与另一个实例进行比较。如果Foo1.A==Foo2.A和Foo1.B==Foo2.B,那么我们有平等。这就是问题所在:Fooone=newFoo(1,2);Foo二=新Foo(2,1);if(one.Equals(two)){...}//这是真的!这些都是GetHashCode()产生值3,导致Equals()返回true。显然,这是一个只有两个属性的简单示例,我可以简单地比较Equals()方法中的各个属性。但是,对于更复杂的类,这很快就会失控。我知道有时只设置一次哈希码并始终返回相同的值是有意义的。但是,对于需要评估是否相等的可变对象,我认为这是不合理的。在实现GetHashCode()时处理易于互换的属性值的最佳方法是什么?另请参阅覆盖System.Object.GetHashCode的最佳算法是什么?首先-不要仅根据GetHashCode()实现Equals()-即使对象不相等,哈希码有时也会发生冲突。GetHashCode()的合同包括以下内容:AndrewHare建议我添加到他的回答中:我建议您阅读此解决方案(由我们自己的JonSkeet,顺便说一句)以获得计算哈希码的“更好”方法。不,以上内容相对较慢并且没有太大帮助。有些人使用XOR(例如a^b^c),但我更喜欢JoshBloch的“EffectiveJava”中所示的方法:publicoverrideintGetHashCode(){inthash=23;hash=hash*37+craneCounterweightID;hash=hash*37+trailerID;hash=hash*37+craneConfigurationTypeCode.GetHashCode();返回散列;}23和37是任意数和普通素数。上述方法优于XOR方法的优点是,如果您的类型有两个通常相同的值,那么对这些值进行异或将始终给出相同的结果(0),而上述方法将区分它们,除非您是很幸运。如上面的代码片段所述,您可能还想查看JoshuaBloch的书“EffectiveJava”,其中包含对该主题的很好处理(哈希码讨论也适用于.NET)。Andrew发布了一个生成更好的哈希码的好例子,但请记住,哈希码不应该用作相等性检查,因为它们不能保证是唯一的。举一个简单的例子,为什么这是一个双对象。它比int有更多的可能取值,所以不可能给每个double一个唯一的int。哈希其实只是第一遍,用在像字典这种需要快速找到key的情况下,先比较哈希,可以排除大部分可能的key,只有和hash匹配的key才需要做代价完全相等检查(或其他冲突解决方法)。哈希总是涉及碰撞,你必须处理它(fe,比较哈希值,如果相等,则比较类中的值,以确保类相等)。使用简单的XOR,您会遇到很多冲突。如果你想要更少,你可以使用一些数学函数,在不同的位上赋值(移位,乘以素数等)。读取覆盖可变对象的GetHashCode?C#并考虑实施IEquatable以实现快速生成和良好的散列分布publicoverrideintGetHashCode(){returnA.GetHashCode()^B.GetHashCode();//XOR}出于好奇,因为哈希码通常是一个比较坏主意,只执行下面的代码不是更好,还是我遗漏了什么?publicoverrideboolEquals(objectobj){boolisEqual=false;FoootherFoo=objasFoo;if(otherFoo!=null){isEqual=(this.A==otherFoo.A)&&(this.B==otherFoo.B);}返回等于;有几个更好的散列实现。例如FNV哈希。以上就是C#学习教程:使用xor的GetHashCode()问题全部内容分享。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: