使用XOR GetHash code()的问题 [英] GetHashCode() problem using xor

查看:123
本文介绍了使用XOR GetHash code()的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的理解是,你通常应该使用XOR与GetHash code()来产生一个int由它的价值,以确定您的数据(通过其参考反对)。这里有一个简单的例子:

 类Foo
{
    INT M_A;
    INT M_B;

    公众诠释一个
    {
        {返回M_A; }
        集合{M_A =价值; }
    }

    公众诠释乙
    {
        {返回M_B; }
        集合{M_B =价值; }
    }

    公共美孚(INT A,INT B)
    {
        M_A =一个;
        M_B = B;
    }

    公众覆盖INT GetHash code()
    {
        回归A ^ B:
    }

    公众覆盖布尔等于(obj对象)
    {
        返回this.GetHash code()== obj.GetHash code();
    }
}
 

的想法是,我想富的一个实例比较,另一个基于性能的A和B的值。如果Foo1.A == Foo2.A和Foo1.B == Foo2.B,那么我们有平等

这里的问题:

 美孚1 =新的Foo(1,2);
美孚2 =新的Foo(2,1);

如果(one.Equals(二)){...} //这是真的!
 

这些都产生了3 GetHash code(A值),造成的equals()返回true。显然,这是一个简单的例子,并且只有两个属性,我可以简单地比较了等于单个属性()方法。然而,在一个更​​复杂的类,这将不可收拾快。

我知道,有时它是有道理的,设置散列code只有一次,而且总是返回相同的值。但是,对于可变对象,其中平等的评估是必要的,我不认为这是合理的。

什么是处理实施GetHash code时可以很容易地进行互换属性值的最佳方法()?

  

另请参见

     

<一个href="http://stackoverflow.com/questions/263400/what-is-the-best-algorithm-for-an-overridden-system-object-gethash$c$c">What是一个覆盖System.Object.GetHash code最好的算法?

解决方案

第一关 - 不实现equals()只在GetHash code项() - 哈希codeS有时会发生冲突,即使对象是不相等的。

该合同GetHash code()包括以下内容:

  • 在不同的hash codeS意味着对象是绝对不等于
  • 在相同的散列codeS是指对象的也许的是相同的(但可能可能不会)

安德鲁野兔建议我将他的回答:

我会建议你读<一href="http://stackoverflow.com/questions/263400/what-is-the-best-algorithm-for-an-overridden-system-object-gethash$c$c">this解决方案(由我们自己的乔恩斯基特,顺便)为一个更好的方式计算散列code。

  

没有,上面是比较缓慢的,   不会有很大的帮助。有些人使用   异或(如^ B ^ C),但我preFER的   一种方法在乔希布洛赫的显示   有效的Java:

 公众覆盖INT GetHash code()
{
    INT哈希= 23;
    哈希散列= * 37 + craneCounterweightID;
    哈希散列= * 37 + trailerID;
    哈希散列= * 37 + craneConfigurationType code.GetHash code();
    返回哈希;
}
 

     

23和37是任意数字   这是互质数。

     

以上在XOR的好处   方法是,如果你有一个类型   它有两个值,它们   经常相同,异或那些   值总是给出相同的   结果(0),而上面会   区分它们,除非   你很倒霉。

正如上面的代码片段,你可能也想看看约书亚布洛赫的书有效的Java,它包含一个很好的处理这个问题的(哈希code讨论适用于.NET一样)。

My understanding is that you're typically supposed to use xor with GetHashCode() to produce an int to identify your data by its value (as opposed to by its reference). Here's a simple example:

class Foo
{
    int m_a;
    int m_b;

    public int A
    {
        get { return m_a; }
        set { m_a = value; }
    }

    public int B
    {
        get { return m_b; }
        set { m_b = value; }
    }

    public Foo(int a, int b)
    {
        m_a = a;
        m_b = b;
    }

    public override int GetHashCode()
    {
        return A ^ B;
    }

    public override bool Equals(object obj)
    {
        return this.GetHashCode() == obj.GetHashCode();
    }
}

The idea being, I want to compare one instance of Foo to another based on the value of properties A and B. If Foo1.A == Foo2.A and Foo1.B == Foo2.B, then we have equality.

Here's the problem:

Foo one = new Foo(1, 2);
Foo two = new Foo(2, 1);

if (one.Equals(two)) { ... }  // This is true!

These both produce a value of 3 for GetHashCode(), causing Equals() to return true. Obviously, this is a trivial example, and with only two properties I could simply compare the individual properties in the Equals() method. However, with a more complex class this would get out of hand quickly.

I know that sometimes it makes good sense to set the hash code only once, and always return the same value. However, for mutable objects where an evaluation of equality is necessary, I don't think this is reasonable.

What's the best way to handle property values that could easily be interchanged when implementing GetHashCode()?

See Also

What is the best algorithm for an overridden System.Object.GetHashCode?

解决方案

First off - Do not implement Equals() only in terms of GetHashCode() - hashcodes will sometimes collide even when objects are not equal.

The contract for GetHashCode() includes the following:

  • different hashcodes means that objects are definitely not equal
  • same hashcodes means objects might be equal (but possibly might not)

Andrew Hare suggested I incorporate his answer:

I would recommend that you read this solution (by our very own Jon Skeet, by the way) for a "better" way to calculate a hashcode.

No, the above is relatively slow and doesn't help a lot. Some people use XOR (eg a ^ b ^ c) but I prefer the kind of method shown in Josh Bloch's "Effective Java":

public override int GetHashCode()
{
    int hash = 23;
    hash = hash*37 + craneCounterweightID;
    hash = hash*37 + trailerID;
    hash = hash*37 + craneConfigurationTypeCode.GetHashCode();
    return hash;
}

The 23 and 37 are arbitrary numbers which are co-prime.

The benefit of the above over the XOR method is that if you have a type which has two values which are frequently the same, XORing those values will always give the same result (0) whereas the above will differentiate between them unless you're very unlucky.

As mentioned in the above snippet, you might also want to look at Joshua Bloch's book, Effective Java, which contains a nice treatment of the subject (the hashcode discussion applies to .NET as well).

这篇关于使用XOR GetHash code()的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆