我想使用一个HashMap
来将(x, y)坐标映射到相应的值上。
那么,hashCode()
函数该如何定义呢?
在这种情况下,我只存储形式为(x, y),且y-x=0,1,...,M-1 (M是某个参数)的整数坐标。
要从两个数字中获取唯一值,可以使用在此处描述的双射算法: < x; y >= x + (y + ( (( x +1 ) /2) * (( x +1 ) /2) ) )
这将为您提供可用于哈希码的唯一值。
public int hashCode()
{
int tmp = ( y + ((x+1)/2));
return x + ( tmp * tmp);
}
我通常使用 Objects.hash(Object... value)
为一系列项生成哈希码。
该哈希码的生成方式,就好像所有输入值都被放置在一个数组中,并通过调用 Arrays.hashCode(Object[]) 对该数组进行哈希。
@Override
public int hashCode() {
return Objects.hash(x, y);
}
对于三维坐标,请使用Objects.hash(x, y, z)
。
如果您希望手动处理它,可以使用以下方式计算hashCode:
// For 2D coordinates
hashCode = LARGE_PRIME * X + Y;
// For 3D coordinates
hashCode = LARGE_PRIME^2 * X + LARGE_PRIME * Y + Z;
你考虑过将x或y的值移动可用位数的一半吗?
对于“经典”的8位,每个轴只有16个单元格,但是对于今天的“标准”32位,每个轴的单元格数量增加到超过65k个。
@override
public int hashCode() {
return x | (y << 15);
}
public override int GetHashCode()
{
unchecked // integer overflows are accepted here
{
int hashCode = 0;
hashCode = (hashCode * 397) ^ this.Hue.GetHashCode();
hashCode = (hashCode * 397) ^ this.Saturation.GetHashCode();
hashCode = (hashCode * 397) ^ this.Luminance.GetHashCode();
return hashCode;
}
}
这个方案也适用于您的坐标,只需将属性替换为X和Y值即可。请注意,我们应该防止整数溢出异常,在DotNet中,可以通过使用unchecked
代码块来实现。
这取决于您打算使用哈希码的目的:
如果您计划将其用作一种索引,例如,知道 x 和 y 将散列为存储 (x, y) 数据的索引,最好使用向量来进行此类操作。
Coordinates[][] coordinatesBucket = new Coordinates[maxY][maxX];
但如果你必须为每个(x,y)组合拥有唯一的哈希值,那么尝试将坐标应用于十进制表格(而不是加法或乘法)。例如,x=20 y=40 将给你一个简单且独特的代码 xy=2040。
31*x+y
。 - k_g