[英]HashCode for mutable object
假设我有一个对象。
它包含宽度和高度,x和y坐标以及x和y代表速度。
我已经覆盖了equals方法,并且通过比较宽度,高度,x和y以及速度来进行比较。
我应该如何处理哈希码?
我之所以感到困惑,是因为它是一个移动的对象,我不确定我应该使用什么来计算哈希码,值将不断变化,而唯一保持静态的是大小。
根据Object.hashCode(),有一个子句可以帮助您做出决定:
在Java应用程序的执行过程中,只要在同一对象上多次调用它,则hashCode方法必须一致地返回相同的整数,前提是未修改该对象的equals比较中使用的信息。 从一个应用程序的执行到同一应用程序的另一执行,此整数不必保持一致。
由于您的equals()
比较宽度,高度,x和y以及速度,因此只要这些值发生变化,您的hashcode()
就不会返回相同的哈希值。
您的示例hashcode()
:
@Override
public int hashCode() {
int hash = 1;
hash = hash * 17 + width;
hash = hash * 31 + height;
hash = hash * 13 + x;
hash = hash * 13 + y;
hash = hash * 13 + velocity.hashcode();
return hash;
}
您可以通过将哈希码存储在私有变量中来进一步进行操作,并在任何参数发生更改时使用dirty
标志来重新计算对象的hashcode
。 由于您没有在hashcode()
方法中执行任何昂贵的操作,因此我认为您不需要这样做。
如果您希望您的哈希码代码比较相等性,那么使用更改的值就很好了,因为哈希是在需要时(或应该)即时计算的。 因此,您拥有所有这些“移动”的东西,并且想知道它们是否相等(它们具有相同的位置或速度或任何东西),那么它将是准确的。
如果要在哈希表中使用它,则不要覆盖它,而要使用默认值(内存中的地址)。 或者,如果要更多控制,请设置一个静态计数器,然后使用该计数器为这些对象创建ID。
只要确保equals()
和hashCode()
一致即可。 这意味着,无论用于确定相等性的任何字段都应用于计算哈希码,以便相等的对象(具有特定状态)将具有相同的哈希码(针对相同状态)。
但是,您可能首先要考虑equals()
实现是否正确,或者是否甚至需要覆盖默认实现。
老实说,我想要实现哈希码的唯一原因是因为Java规则规定如果覆盖equals,那么哈希码也应该是。 但是,在地图中不会使用任何对象。
在这种情况下,您可以按以下方式实现它:
public int hashCode() {
throw new UnsupportedOperationException("hashCode is not implemented");
}
这样做的好处是,如果您不小心将对象用作哈希键,则如果在错误的时间对对象进行了更改,您将立即获得异常而不是意外的行为。
通常,我会向对象分配一个ID作为成员变量,然后将该ID作为哈希码值返回。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.