将哈希码作为简单增量可以吗?

时间:2015-03-31 06:42:38

标签: java hash

对于hashCode,这个代码是否可以是一个以负数开头的简单增量?

private volatile static AtomicInteger creations = new AtomicInteger(Integer.MIN_VALUE);
private final int creation;

{
    creation = creations.getAndIncrement();
}

@Override
public int hashCode() {
    return creation;
}

@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    if (creation == ((Stuff) obj).creation)
        return true;
    else
        return false;
}

为什么hashCodes通常使用素数而不是仅使用简单的增量? (之所以我希望它是这样的,是因为我用这个类创建的每个对象都是唯一的,我希望以后能够从HashMap中删除它,即使对象的状态会改变,因为它是我的了解Hash是否发生了变化,然后在添加HashMap后无法将其从HashMap中删除。为了防止这是一个简单的是或否答案,可以向我解释以这种方式实现Hash的利弊。

2 个答案:

答案 0 :(得分:2)

一般来说,它不行。 object1.equals(object2)返回true的两个对象必须具有相同的hashCode

但是,在您的特定情况下,对象相等的唯一标准是创建属性,这与hashCode中使用的属性相同,您的hashCode就可以了。

但是,与hashCode的默认实施相比,equalsObject没有提供太多好处,因为a.equals(b)当前且仅当a==b为真{1}}。

答案 1 :(得分:2)

是的它没关系(如果两个实例是等号,它们具有相同的哈希码)虽然你的equals / hashcode实现与Object的默认实现没有太大关系,所以没有必要这样做 - 除非你希望每2 ^ 32个实例创建对象相等。

根据您的补充,我同意Patricia Shanahan建议使用identityHashCode

@Override
public int hashCode() {
  return System.identityHashCode(this);
}

@Override
public boolean equals(Object obj) {
 return this == obj;
}

这实际上是Object默认执行的操作。在碰撞方面,我怀疑你与这个实现的冲突会比你的更多。