【问题标题】:How to override GetHashCode on a Hashtable?如何覆盖哈希表上的 GetHashCode?
【发布时间】:2018-05-04 10:22:06
【问题描述】:

我想在 C# 中覆盖哈希表上的 GetHashCode 方法。

我将哈希表用作复杂对象中的多维键。

怎么会这样?

hKey 中不同顺序的键必须返回相同的hashCode

这样的事情是行不通的:

Hashtable hkey; 

int i = 0;
foreach (DictionaryEntry de in hkey)
    i ^= de.GetHashCode();

return i;

【问题讨论】:

  • 你试过什么?您可以通过继承要更改的类来覆盖GetHashCode,然后改用新的子类。
  • 为什么你仍然使用HashTable而不是Dictionary<SomeType, SomeType>
  • 嗯,XOR 运算符不关心顺序,所以“不起作用”的抱怨没有帮助。当 GetHashCode() 变得太慢时,它很快就会变得无用,迭代整个集合是不正确的。考虑return hkey.Count;
  • 看我下面的帖子问题来自dictionaryEntry的GetHashCode,它只考虑了关键部分。关于性能,我保留了 HashCode 的缓存;)

标签: c# hashtable gethashcode


【解决方案1】:

如果你像这样扩展它,你可以覆盖哈希表的 GetHashCode():

public class MyHashtable : Hashtable
{
    public override int GetHashCode()
    {
        const int seed = 1009;
        const int factor = 9176;

        var hash = seed;
        foreach (var key in Keys)
        {
            hash = hash * factor + key.GetHashCode();
        }

        return hash;
    }
}

常数取自这个答案:https://stackoverflow.com/a/34006336/8006950

更多关于散列的信息:http://www.eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx

【讨论】:

    【解决方案2】:

    好的,谢谢大家

        static void Main(string[] args)
        {
            Hashtable h = new Hashtable()
            {
              { "string1", 1 },
              { "string2", 2 }
            };
    
            int i = GetHashCode(h);
    
            h = new Hashtable()
            {
              { "string2", 2},
              { "string1", 1 }
            };
    
            int j = GetHashCode(h);
    
            Debug.Assert(i == j);
    
            h = new Hashtable()
            {
              { "string1", 1 },
              { "string2", 2 }
            };
    
            i = GetHashCode(h);
    
            h = new Hashtable()
            {
              { "string2", 3},
              { "string1", 1 }
            };
    
            j = GetHashCode(h);
    
            Debug.Assert(i != j);
        }
    
        static int GetHashCode(Hashtable ht)
        {
            if (ht.Count == 0) return ht.GetHashCode();
    
            int h = 0;
            foreach(DictionaryEntry de in ht)
            {
                h ^= new { de.Key, de.Value }.GetHashCode();
            }
            return h;
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-21
      • 2014-02-17
      • 1970-01-01
      • 2012-07-13
      • 1970-01-01
      • 2017-05-02
      相关资源
      最近更新 更多