我们有以下代码:
int i = 1;
Console.WriteLine(i.GetHashCode()); // outputs => 1
这是有道理的,除了 sbyte 和 short 之外,C# 中的所有整数类型都会发生同样的情况。那是:
sbyte i = 1;
Console.WriteLine(i.GetHashCode()); // outputs => 257
为什么是这样?
因为该方法 ( SByte.GetHashCode
) 的来源是
public override int GetHashCode()
{
return (int)this ^ ((int)this << 8);
}
至于为什么,微软的某个人知道..
是的,这都是关于价值分配的。由于 GetHashCode 方法的返回类型是 sbyte 类型的 int,因此值将以 257 的间隔分布。出于同样的原因,long 类型将是 colisions。
原因是这样做可能是为了避免散列值的聚类。
正如GetHashCode
文件所说:
为了获得最佳性能,散列函数必须为所有输入生成随机分布。为类提供良好的散列函数会显着影响将这些对象添加到散列表的性能。在具有良好实现散列函数的散列表中,搜索元素需要恒定时间(例如,O(1) 操作)。
此外,正如这篇出色的文章所解释的:
准则:散列码的分布必须是“随机的” “随机分布”是指如果被散列的对象有共同点,那么在产生的散列码中不应该有相似的共同点。例如,假设您正在散列一个表示一个点的纬度和经度的对象。一组这样的位置很可能是“聚集”的;例如,您的一组位置很有可能是同一城市中的大多数房屋,或者同一油田中的大多数阀门,或其他任何地方。如果集群数据产生集群哈希值,那么这可能会减少使用的桶数,并在桶变得非常大时导致性能问题。