当您创建自己的密钥对对象时,您应该注意几件事情。
首先,您应该注意实现 hashCode() 和 equals()。 您需要这样做。
其次,在实现 hashCode() 时,请确保您了解它的工作原理。 给出了用户示例
public int hashCode() {
return this.x ^ this.y;
}
实际上,这是你可以做的最糟糕的实现之一。原因很简单:你有很多相等的哈希值!而hashCode()应该返回倾向于稀有、最好是唯一的int值。使用类似这样的东西:
public int hashCode() {
return (X << 16) + Y;
}
这是一种快速且返回介于-2^16和2^16-1(-65536到65535)之间的唯一哈希键的方法。几乎适用于所有情况。很少会超出这个范围。
第三,当实现equals()时,要知道它的用途,并注意如何创建键,因为它们是对象。通常您会做不必要的if语句,因为您始终会得到相同的结果。
如果您像这样创建键:map.put(new Key(x,y),V);,则永远不会比较您的键的引用。因为每次您要访问地图时,都会执行类似于map.get(new Key(x,y));的操作。因此,您的equals()不需要像if (this == obj)这样的语句。它将永远不会出现。
在您的equals()中,与其使用if(getClass() != obj.getClass()),不如使用if(!(obj instanceof this))。即使对于子类也是有效的。
所以您唯一需要比较的事情实际上就是X和Y。因此,在这种情况下最好的equals()实现如下:
public boolean equals (final Object O) {
if (!(O instanceof Key)) return false;
if (((Key) O).X != X) return false;
if (((Key) O).Y != Y) return false;
return true;
}
最终,您的关键类如下所示:
public class Key {
public final int X;
public final int Y;
public Key(final int X, final int Y) {
this.X = X;
this.Y = Y;
}
public boolean equals (final Object O) {
if (!(O instanceof Key)) return false;
if (((Key) O).X != X) return false;
if (((Key) O).Y != Y) return false;
return true;
}
public int hashCode() {
return (X << 16) + Y;
}
}
由于维度索引 X 和 Y 是常量且不包含敏感信息,因此您可以将它们的公共访问级别设置为public。我不能100%确定在将 Object 强制转换为 Key 时,private 访问级别是否在任何情况下都能正常工作。
如果您对这些常量有疑问,我会将任何值在实例化时设置并且永远不会更改的内容声明为常量 - 因此是对象常量。