繁体   English   中英

获取一个int和Nullable的哈希码 <int> 对

[英]Get hash code for an int and a Nullable<int> pair

当前,我将以下类用作我的Dictionary集合的键,该对象集合由ColumnID和可为空的SubGroupID

public class ColumnDataKey
{
    public int ColumnID { get; private set; }
    public int? SubGroupID { get; private set; }

    // ...

    public override int GetHashCode()
    {
        var hashKey = this.ColumnID + "_" + 
            (this.SubGroupID.HasValue ? this.SubGroupID.Value.ToString() : "NULL");
        return hashKey.GetHashCode();
    }
}

我正在考虑以某种方式将其组合为64位整数,但不确定如何处理null的SubGroupIDs 据我所知,但这是无效的,因为SubGroupID可以为零:

var hashKey = (long)this.ColumnID << 32 + 
    (this.SubGroupID.HasValue ? this.SubGroupID.Value : 0);
return hashKey.GetHashCode();

有任何想法吗?

严格来说,由于逻辑上int?您将无法完美地结合这些功能int? 具有33位信息(32位为整数,另一位表示该值是否存在)。 您的不可为空的int具有另外32位信息,总共65位,而long只有64位。

如果您可以安全地将任何一个int的值范围限制为仅31位,那么您就可以像已经做的那样大致打包它们。 但是,这样做不会有任何好处-您最好直接像这样计算哈希码(这要感谢Resharper的样板代码生成):

public override int GetHashCode()
{
    unchecked
    {
        return (ColumnID*397) ^ (SubGroupID.HasValue ? SubGroupID.Value : 0);
    }
}

您似乎正在考虑将GetHashCode作为唯一键。 不是。 HashCode是32位整数,并非唯一,只能在32位空间中均匀分布以最大程度地减少冲突的可能性。 对于ColumnDataKey的GetHashCode方法,请尝试以下操作:

ColumnID * 397 ^ (SubGroupID.HasValue ?? SubGroupID.Value : -11111111)

这里的魔术数字是397,是质数,出于伏都教魔术的原因,它是乘以混合您的位的好数字(这是ReSharper团队选择的数字),以及-11111111,我认为是子组ID实际上不太可能出现。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM