如何生成唯一的哈希码?

时间:2019-01-11 07:44:15

标签: c# hashcode

所以,我有这个结构。它具有一些功能和运算符,但并不重要。

public struct Vector3
{
    public float X, Y, Z;
}

我正在通过HashTable过滤这些集合,并且工作正常。但我想验证仅删除重复项。默认情况下,我的IDE为 GetHashCode()方法提供了以下代码:

public override int GetHashCode()
{
    var hashCode = -307843816;
    hashCode = hashCode * -1521134295 + X.GetHashCode();
    hashCode = hashCode * -1521134295 + Y.GetHashCode();
    hashCode = hashCode * -1521134295 + Z.GetHashCode();
    return hashCode;
}

对我来说,哪条看起来像是在钓鱼。我非常确定,仅这些因素会在INT_32上产生溢出。此外,我很困惑,所有三个浮子似乎都具有相同的“重量”(-1521134295)。另外,我不太确定float的 GetHashCode()是做什么的。有点模式本身应该已经是唯一的。

从96位输入创建唯一的32位模式必须是不可能的。

那它如何工作?

  • 在使用HashMap删除项目之前,HashMap是否使用equal方法吗? 相同的HashCode。

  • 我只是幸运吗?

  • 我的IDE生成的这些数字分别是“权重”和 起始值?

PS::对于那些感兴趣的人,该结构的代码在这里。

public struct Vector3
{
    public float X, Y, Z;

    public Vector3(float x, float y, float z)
    {
        X = x;
        Y = y;
        Z = z;
    }     

    public static bool operator ==(Vector3 a, Vector3 b)
    {
        return (a.X == b.X && a.Y == b.Y && a.Z == b.Z);
    }

    public static bool operator !=(Vector3 a, Vector3 b)
    {
        return (a.X != b.X || a.Y != b.Y || a.Z != b.Z);
    }

    public static Vector3 operator +(Vector3 a, Vector3 b)
    {
        return new Vector3(a.X + b.X, a.Y + b.Y, a.Z + b.Z);
    }

    public static Vector3 operator -(Vector3 a, Vector3 b)
    {
        return new Vector3(a.X - b.X, a.Y - b.Y, a.Z - b.Z);
    }

    public float Magnitued
    {
        get
        {
            return (float)Math.Sqrt((X * X) + (Y * Y) + (Z * Z));
        }
        private set { }
    }

    public Vector3 Normalized
    {
        get
        {
            var mag = Magnitued;
            return new Vector3(X / mag, Y / mag, Z / mag);
        }

        private set { }
    }

    public override bool Equals(object obj)
    {
        if (!(obj is Vector3))
        {
            return false;
        }

        var vector = (Vector3)obj;
        return X == vector.X && Y == vector.Y && Z == vector.Z;
    }

    public override int GetHashCode()
    {
        var hashCode = -307843816;
        hashCode = hashCode * -1521134295 + X.GetHashCode();
        hashCode = hashCode * -1521134295 + Y.GetHashCode();
        hashCode = hashCode * -1521134295 + Z.GetHashCode();
        return hashCode;
    }
}

1 个答案:

答案 0 :(得分:1)

我认为您在这里有误会。哈希码不应该是唯一的,因为正如您所观察到的,有时是不可能的

主要要求是被视为“相等”的对象应具有相同的哈希码。

只要满足要求,就可以造成溢出。

这在documentation中也有说明:

  

两个相等的对象返回相等的哈希码。但是,事实并非如此:相等的哈希码并不意味着对象相等,因为不同的(不相等)对象可以具有相同的哈希码。

您还可以在链接的页面中查看GetHashCode的其他实现。