如何从三个long生成哈希码
我有一个坐标为键的HashMap。
坐标有3个长度,保持x,y和z坐标。 (坐标是并且需要是一个自定义类,坐标需要很长)。
现在我希望能够通过执行以下hashMap.get(new Coordinate(5, 10, 4))
来访问例如字段[ hashMap.get(new Coordinate(5, 10, 4))
]: hashMap.get(new Coordinate(5, 10, 4))
。
我已经实现了equals方法,但这还不够,因为显然我还需要为hashCode提供一个实现。 所以我的问题是如何从三个长度生成一个独特的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; } }
在Java中,标准的hashCode()
方法返回int
,即32位。
long
数据类型是64位。 因此,三个long
s表示192位信息,当然不能通过任何散列函数将其唯一地映射到仅32位的散列值。
但是, HashMap
不需要唯一的散列,它只会在碰撞发生时处理它们。
一种天真的方式是构建字符串,即“x,y,z”,然后散列字符串。
您也可以尝试XOR:将值组合在一起:
int hashCode() { return (int) (x ^ y ^ z); }
如何从三个长度生成一个唯一的hashCode?
你不需要。 哈希码不必是唯一的。
您应该意识到哈希码和要在HashMap中使用的唯一键之间存在差异。
您的Coordinate类的哈希码根本不必是唯一的……
哈希码的一个很好的解决方案是:
(int)(x ^ (x >> 32) ^ y ^ (y >> 32) ^ z ^ (z >> 32));
这是每个长矛的两个异或的两个异或。