为什么GetHashCode方法需要在C#中进行移位

这个问题在这里已经有了答案:

  • 什么是重写的System.Object.GetHashCode的最佳算法? 17个答案

  • 我不能说他们为什么选择这个特定的哈希代码实现,但对于这个问题:

  • 为什么该方法首先进行右移(32位),然后进行左移位置,它有特定的含义吗?
  • 这里的ShiftAndWrap()方法是一种算法的通用实现,用于将值左移N位,并将溢出包回到结尾。 所以在他们进行转换之前,他们首先得到最左边的N位,这样他们就可以将它们追加到最后。

    因此,如果我们只使用8位值( byte s)并将其称为value =(二进制)11010010和positions = 3,则调用ShiftAndWrap()将看起来像这样:

    value = 11010010
    
    positions = 3
    
    wrapped = value >> (8 - positions)
            = 11010010 >> (8 - 3) 
            = 11010010 >> 5 
            = 00000110
    
    result = value << positions | wrapped
           = 11010010 << 3 | 00000110 
           = 10010000 | 00000110 
           = 10010110
    

    我们可以看到,返回值10010110是将11010010移位三位并包围结果的结果。


    至于他们为什么不使用x ^ y ,我怀疑这是因为这意味着Point(N, M)将总是产生与Point(M, N)相同的散列码。 通过对x值进行移位,我们可以得到一个哈希码,它不仅考虑xy值,还考虑它们的顺序,而x ^ y会忽略它们的顺序。

    在对包含相同类型子组件的数据结构进行散列处理时,散列函数对每个子组件进行不同处理是很常见的,因此它们的位置很重要。 例如,Java使用这个散列公式来表示字符串(这里^表示一个指数,而不是XOR):

    s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
    

    我们可以看到,每个字符乘以31的不同幂,所以stop具有与pots不同的散列码。

    至于他们为什么选择2作为转移职位的数量,可能是任意的,或者他们可能已经做了一些评估,看看可能产生最佳分配的转变程度。


    HashCode的要点是创建一个分布,以便数据结构可以将数据分配到特定的桶中。 它并不意味着平等。

    如果您查看HashSet的内部结构,您可以看到该类使用HashCode标识正确的存储桶,然后使用Equals方法确定相等性。

        /// <summary>
        /// Checks if this hashset contains the item
        /// </summary>
        /// <param name="item">item to check for containment</param>
        /// <returns>true if item contained; false if not</returns>
        public bool Contains(T item) {
            if (m_buckets != null) {
                int hashCode = InternalGetHashCode(item);
                // see note at "HashSet" level describing why "- 1" appears in for loop
                for (int i = m_buckets[hashCode % m_buckets.Length] - 1; i >= 0; i = m_slots[i].next) {
                    if (m_slots[i].hashCode == hashCode && m_comparer.Equals(m_slots[i].value, item)) {
                        return true;
                    }
                }
            }
            // either m_buckets is null or wasn't found
            return false;
        }
    

    所以碰撞很好,它只是在那里,所以确保一个相对平等的分布,以便更快地识别和检索。 这意味着,在你的情况下,这两个点将被放置在同一个桶中,但它们的Equals方法将用于识别它们。

    链接地址: http://www.djcxy.com/p/39773.html

    上一篇: Why GetHashCode method needs to do shift in C#

    下一篇: How to implement GetHashCode() in a C# struct