所以,我有这个结构。它覆盖了一些函数和运算符,但这并不那么重要。
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上产生溢出。此外,我感到困惑的是,所有三个浮子似乎都有相同的"重量"(-1521114295)。另外,我真的不确定float的GetHashCode()做什么。它的bit模式本身应该已经是唯一的了。
从96位的输入中创建一个独特的32位模式是不可能的。
那么它是如何工作的呢
在使用相同的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;
}
}
我想你在这里有一个误解。哈希码不应该是唯一的,因为正如您所观察到的,有时是不可能的
主要要求是被认为"相等"的对象应该具有相同的哈希代码。
只要满足要求,导致溢出是可以的。
这在文件中也有说明:
两个相等的对象返回相等的哈希代码。然而,事实并非如此:相等的散列码并不意味着对象相等,因为不同(不相等)的对象可以具有相同的散列码。
您还可以在链接页面中看到GetHashCode
的其他实现。