[英]How to generate a hash code from three longs
我有一个以坐标为键的 HashMap。
坐标有 3 个 longs 保存 x、y 和 z 坐标。 (坐标是并且需要是自定义类,坐标需要是长整数)。
现在我希望能够通过执行以下hashMap.get(new Coordinate(5, 10, 4))
来访问例如字段 [5, 10, 4] : hashMap.get(new Coordinate(5, 10, 4))
。
我已经实现了 equals 方法,但这还不够,因为显然我还需要为 hashCode 提供一个实现。 所以我的问题是如何从三个 long 生成唯一的 hashCode? .
附加:使用来自外部库的哈希生成器不是选项。
Joshua Bloch 在他的“Effective Java”的 第 3 章中告诉你如何为你的 Coordinate 类编写 equals 和 hashCode。
像这样:
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;
}
}
这是一个老问题,但如果有人碰到它,现在有一个更简单的方法来做到这一点:
@Override
public int hashCode() {
return Objects.hash(x, y, z);
}
在 Java 中,标准的hashCode()
方法返回int
,它是 32 位。
long
数据类型是 64 位。 因此,三个long
s 意味着 192 位信息,当然不能通过任何哈希函数将其唯一映射到仅 32 位的哈希值。
然而, HashMap
不需要唯一的散列,它会在冲突发生时简单地处理它们。
一种天真的方法是构建字符串,即“x,y,z”,然后对字符串进行散列。
你也可以尝试只异或:将值放在一起:
int hashCode()
{
return (int) (x ^ y ^ z);
}
如何从三个 long 生成唯一的 hashCode?
你不需要。 哈希码不需要是唯一的。
您应该意识到哈希码和要在 HashMap 中使用的唯一键之间存在差异。
您的 Coordinate 类的哈希码根本不必是唯一的...
哈希码的一个很好的解决方案是:
(int)(x ^ (x >> 32) ^ y ^ (y >> 32) ^ z ^ (z >> 32));
这是对每个 long 的两半进行异或运算的异或。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.