Java 如何从三个long生成哈希代码
我有一个以坐标为键的HashMap 坐标有3个长度,分别代表x、y和z坐标。(坐标是并且必须是自定义类,坐标必须是long) 现在,我希望能够通过执行以下操作访问字段[5,10,4]:Java 如何从三个long生成哈希代码,java,hashcode,hash-code-uniqueness,Java,Hashcode,Hash Code Uniqueness,我有一个以坐标为键的HashMap 坐标有3个长度,分别代表x、y和z坐标。(坐标是并且必须是自定义类,坐标必须是long) 现在,我希望能够通过执行以下操作访问字段[5,10,4]:hashMap.get(新坐标(5,10,4)) 我已经实现了equals方法,但这还不够,因为显然我还需要为hashCode提供一个实现。所以我的问题是如何从三个long生成唯一的hashCode 附加:使用外部库中的哈希生成器是不可取的。Joshua Bloch告诉您如何在他的“有效Java”中为坐标类编写等号
hashMap.get(新坐标(5,10,4))
我已经实现了equals方法,但这还不够,因为显然我还需要为hashCode提供一个实现。所以我的问题是如何从三个long生成唯一的hashCode
附加:使用外部库中的哈希生成器是不可取的。Joshua Bloch告诉您如何在他的“有效Java”中为坐标类编写等号和哈希代码 像这样:
public class Coordinate
{
private long x;
private long y;
private long z;
@Override
public boolean equals(Object o)
{
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Coordinate that = (Coordinate) o;
if (x != that.x) return false;
if (y != that.y) return false;
if (z != that.z) return false;
return true;
}
@Override
public int hashCode()
{
int result = (int) (x ^ (x >>> 32));
result = 31 * result + (int) (y ^ (y >>> 32));
result = 31 * result + (int) (z ^ (z >>> 32));
return result;
}
}
在Java中,标准的
hashCode()
方法返回int
,即32位
long
数据类型为64位。因此,三个long
s意味着192位的信息,当然不能通过任何哈希函数唯一地映射为32位的哈希值
但是,HashMap
不需要唯一的散列,它只需在冲突发生时处理冲突
一种简单的方法是构建字符串,即“x,y,z”,然后散列字符串
您也可以尝试将这些值进行异或运算:
int hashCode()
{
return (int) (x ^ y ^ z);
}
如何生成唯一的哈希代码
三个龙
你不需要。哈希代码不要求是唯一的。您应该意识到哈希代码和要在哈希映射中使用的唯一键之间存在差异 坐标类的哈希代码不必是唯一的 哈希代码的一个好解决方案是:
(int)(x ^ (x >> 32) ^ y ^ (y >> 32) ^ z ^ (z >> 32));
这是一个古老的问题,但如果有人碰到它,现在有一个更简单的方法来解决:
@Override
public int hashCode() {
return Objects.hash(x, y, z);
}
+1对于有趣的链接,如果我这样计算,整数很有可能会溢出,是不是以前的方式?现在,它不会溢出了。您将返回一个有意义的int。但是我取long1=Integer.MAX_值,long2=5和long3=10,结果将在某个点上流过no?至少当我得到结果*37的时候?我只是想完全理解,如果我stubborn@Samuel,hashcode的目的是均匀分布和伪随机。它是一个散列函数,不是唯一的。;)好的,非常感谢,我可能会使用这本书不仅仅是为了这个:)@Carlos:一个标准语言功能,被数百万程序使用,总是比编写自己的更容易和安全:)你的建议(x+y+z)将导致(0+0+1)或(1+0+0)或(0+1+0)的冲突。使用已经开发、验证、测试和重新测试了数百万次的语言的标准特性总是更安全的。