创建自己的密钥对对象时,您应该面对一些问题。
首先,您应该意识到实现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()
也要知道它的作用,并要知道创建密钥的方式,因为它们是对象。如果语句导致您总是会有相同的结果,那么您通常不需要做很多事情。
如果创建这样的密钥:map.put(new Key(x,y),V);
您将永远不会比较密钥的引用。因为每次您要访问地图时,您都将执行map.get(new Key(x,y));
。因此,您equals()
不需要类似的声明if (this == obj)
。它永远不会发生。
而不是if (getClass() != obj.getClass())
在你equals()
更好地利用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
公共访问级别,因为它们是最终的并且不包含敏感信息。我不是100%肯定是否private
访问级别正常工作在任何铸造时情况Object
的Key
。
如果您对final感到疑惑,那么我将声明为final的任何实例声明为实例化时设置的值,并且永远不会更改-因此是一个对象常量。