Java 很好的二维坐标hashcode函数

Java 很好的二维坐标hashcode函数,java,hash,hashmap,hashcode,Java,Hash,Hashmap,Hashcode,我想用一个 将(x,y)坐标映射到值。 什么是好的hashCode()函数定义? 在本例中,我只存储形式(x,y)的整数坐标 其中,对于某些参数M,y-x=0,1,…,M-1。要从两个数字中获得唯一值,可以使用中描述的双射算法 =x+(y+((x+1)/2)*((x+1)/2))) 这将为您提供unquie值,该值可用于hashcode public int hashCode() { int tmp = ( y + ((x+1)/2)); return

我想用一个 将(x,y)坐标映射到值。 什么是好的
hashCode()
函数定义? 在本例中,我只存储形式(x,y)的整数坐标
其中,对于某些参数M,y-x=0,1,…,M-1。

要从两个数字中获得唯一值,可以使用中描述的双射算法 =x+(y+((x+1)/2)*((x+1)/2)))

这将为您提供unquie值,该值可用于hashcode

public int hashCode()
{
      int tmp = ( y +  ((x+1)/2));
               return x +  ( tmp * tmp);
}

要为具有多个属性的对象计算哈希代码,通常需要实现一个通用解决方案。此实现使用常量因子来组合属性,该因子的值是一个主题。似乎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中,这可以通过使用
未选中的
块来实现。

您是否考虑过简单地将x或y移位一半可用位

对于“经典”8位,它仅为16个单元/轴,但对于今天的“标准”32位,它增长到超过65k个单元/轴

@override
public int hashCode() {
    return x | (y << 15);
}
@覆盖
公共int hashCode(){

返回x |(yI通常使用
Objects.hash(Object…value)
为一系列项生成哈希代码

哈希代码的生成就像所有输入值都被放入一个数组中一样,该数组通过调用Arrays.hashCode(Object[])进行哈希处理

对三维坐标使用
Objects.hash(x,y,z)

如果希望手动处理,可以使用以下方法计算哈希代码:-

// For 2D coordinates
hashCode = LARGE_PRIME * X + Y;

// For 3D coordinates
hashCode = LARGE_PRIME^2 * X + LARGE_PRIME * Y + Z;

这取决于您打算对以下内容使用哈希代码:

如果您计划将其用作一种索引,例如,知道x和y将散列到存储(x,y)数据的索引中,那么最好使用向量

Coordinates[][] coordinatesBucket = new Coordinates[maxY][maxX];

但是,如果绝对必须为每个(x,y)组合使用唯一的哈希,那么请尝试将坐标应用于十进制表(而不是加法或乘法)。例如,x=20y=40将为您提供简单且唯一的代码xy=2040。

我认为默认的eclipse哈希生成器将提供
31*x+y
您希望只查找精确匹配还是几乎相等的坐标?@martinstoeckli我只对查找精确匹配感兴趣,即使用键(x,y)获取值并用键(x,y)来设置值。欢迎来到这里。我想你可能在这里做一个有效的点,但是你的帖子可能会关闭,因为它不遵循这样的Q和A格式。考虑把你的文章作为对OP问题的回答,并添加一个代码和/或你的解决方案将如何解决的其他例子。非常有用。谢谢!
Coordinates[][] coordinatesBucket = new Coordinates[maxY][maxX];