HashCode为可变对象

时间:2015-01-31 01:44:38

标签: java

假设我有一个对象 它包含宽度和高度,x和y坐标,以及表示速度的x和y 我已经覆盖了equals方法,我通过比较宽度,高度,x和y以及速度进行比较 我该怎么处理哈希码?

我感到困惑的原因是它是一个移动的对象,我不确定我应该使用什么来计算哈希码,值会不断变化,唯一保持静态的是大小真。

5 个答案:

答案 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作为哈希码值返回。