如何从三个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)); 

这是每个长矛的两个异或的两个异或。