假设我有一个对象 它包含宽度和高度,x和y坐标,以及表示速度的x和y 我已经覆盖了equals方法,我通过比较宽度,高度,x和y以及速度进行比较 我该怎么处理哈希码?
我感到困惑的原因是它是一个移动的对象,我不确定我应该使用什么来计算哈希码,值会不断变化,唯一保持静态的是大小真。
答案 0 :(得分:2)
根据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()
方法中没有做任何昂贵的事情,我认为您不需要这样做。
答案 1 :(得分:1)
如果您希望您的哈希码代码比较相等,那么使用更改的值就可以了,因为哈希是在您需要时(或应该)动态计算的。所以你拥有所有这些“移动”的东西,你想知道它们是否相等(它们具有相同的位置或速度或其他),那么它将是准确的。
如果要在哈希表中使用它,请不要覆盖它,只使用默认值(内存中的地址)。或者,如果您想要更多控件设置静态计数器并使用它来为这些对象创建ID。
答案 2 :(得分:1)
确保equals()
和hashCode()
一致。
这意味着,用于确定相等性的任何字段都应该用于计算哈希码,以便相等的对象(具有特定状态)将具有相同的哈希码(对于相同的状态)。
但您可能想要首先考虑您的equals()
实现是否正确,或者您是否需要覆盖默认实现。
答案 3 :(得分:1)
老实说,我想要实现哈希代码的唯一原因是因为java规则声明如果equals被覆盖,那么哈希代码也应该如此。但是,没有任何对象将在地图中使用。
在这种情况下,您可以按如下方式实现它:
public int hashCode() {
throw new UnsupportedOperationException("hashCode is not implemented");
}
这样做的好处是,如果您不小心将对象用作哈希键,那么如果对象在错误的时间发生变异,您将获得立即异常,而不是意外行为。
答案 4 :(得分:0)
通常,我会将ID作为成员变量分配给对象,并将ID作为哈希码值返回。