我有一个坐标为键的HashMap。
坐标有3个长按住x,y和z坐标。 (坐标是并且需要是一个自定义类,坐标需要很长)。
现在我希望能够访问例如字段[5,10,4]:hashMap.get(new Coordinate(5, 10, 4))
。
我已经实现了equals方法,但这还不够,因为显然我还需要为hashCode提供一个实现。所以我的问题是如何从三个长点生成一个唯一的hashCode? b>。
附加:使用外部库中的哈希生成器不是选项。
答案 0 :(得分:16)
Joshua Bloch告诉你如何在他的“Effective Java”的chapter 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;
}
}
答案 1 :(得分:3)
在Java中,标准hashCode()
方法返回int
,即32位。
long
数据类型为64位。因此,三个long
s表示192位信息,当然不能通过任何哈希函数唯一地映射到32位哈希值。
但是,HashMap
不需要唯一的散列,它只会在碰撞发生时处理。
一种天真的方式是构建字符串,即“x,y,z”,然后散列字符串。
您也可以尝试XOR:将值组合在一起:
int hashCode()
{
return (int) (x ^ y ^ z);
}
答案 2 :(得分:2)
如何生成唯一的hashCode 来自三个多头?
你不需要。哈希码不必是唯一的。
答案 3 :(得分:2)
这是一个古老的问题,但是如果有人碰到它,现在有一种更简单的方法可以实现:
ARRAYFORMULA
答案 4 :(得分:1)
您应该意识到哈希码和要在HashMap中使用的唯一键之间存在差异。
您的Coordinate类的哈希码根本不必是唯一的......
哈希码的一个很好的解决方案是:
(int)(x ^ (x >> 32) ^ y ^ (y >> 32) ^ z ^ (z >> 32));
对于每个长征的两个异或的两个异或而言,这是异或。