繁体   English   中英

可变对象的HashCode

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM