我想使用HashMap
将(x,y)坐标映射到值。
什么是好的hashCode()
函数定义?
在这种情况下,我只存储形式(x,y)的整数坐标
其中y - x = 0,1,...,M - 1用于某些参数M。
答案 0 :(得分:3)
要从两个数字中获取唯一值,您可以使用here中描述的双射算法 < X; y> = x +(y +(((x +1)/ 2)*((x +1)/ 2)))
这将为您提供unquie值,可用于哈希码
public int hashCode()
{
int tmp = ( y + ((x+1)/2));
return x + ( tmp * tmp);
}
答案 1 :(得分:1)
要计算具有多个属性的对象的哈希码,通常会实现通用解决方案。此实现使用常量因子来组合属性,因子的值是discussions的主题。似乎33或397因子通常会导致散列码的良好分布,因此它们适用于字典。
这是C#中的一个小例子,虽然它应该很容易适用于Java:
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
块来实现。
答案 2 :(得分:1)
您是否考虑过将x或y移动一半的可用位?
对于“经典”8位,只有16个单元/轴,但今天的“标准”32位,它增长到65k以上的单元/轴。
@override
public int hashCode() {
return x | (y << 15);
}
由于显而易见的原因,只有x和y都介于0和0xFFFF(0-65535,包括0和655)之间,这才有效,但是这个空间足够大,超过4.2bio单元格。
编辑: 另一种选择,但要求你知道实际尺寸,就是做x + y *宽度(其中宽度为x的方向为x)
答案 3 :(得分:1)
我通常使用Objects.hash(Object... value)
为一系列项目生成哈希码。
生成哈希码就像将所有输入值都放在一个数组中一样,然后通过调用Arrays.hashCode(Object [])对那个数组进行哈希处理。
@Override
public int hashCode() {
return Objects.hash(x, y);
}
将Objects.hash(x, y, z)
用于3D坐标。
如果您希望手动处理它,则可以使用以下方法计算hashCode:-
// For 2D coordinates
hashCode = LARGE_PRIME * X + Y;
// For 3D coordinates
hashCode = LARGE_PRIME^2 * X + LARGE_PRIME * Y + Z;
答案 4 :(得分:0)
这取决于您打算将哈希码用于:
如果您打算将其用作一种索引,例如知道 x 和 y 将散列到存储 (x, y) 数据的索引中,最好使用向量来处理这种事情。
Coordinates[][] coordinatesBucket = new Coordinates[maxY][maxX];
但是,如果您绝对必须为每个 (x, y) 组合提供唯一的哈希值,那么请尝试将坐标应用于十进制表(而不是相加或相乘)。例如,x=20 y=40 将为您提供简单且唯一的代码 xy=2040。