是永远计算和覆盖hashCode的好习惯

时间:2012-09-25 09:24:50

标签: java

我使用OpenSource OODB db4o,我的序列化类继承自一个常见的abstract.class,它有两个字段:

. . .
private final Long timeCreate = (System.currentTimeMillis() << 20) + (System.nanoTime() & 0xfffff);
private final int hashCode = timeCreate.hashCode();
. . . 
@Override
public final int hashCode() {
    return hashCode;
}
. . .

这样做是不是很好?

我试过的基准测试给出了更快的响应,但是在某些地方嵌套了一个陷阱?

3 个答案:

答案 0 :(得分:1)

理想情况下,对象的hashCode在任何情况下都不应更改。一种选择是仅按需生成它,但在您的情况下,您遇到的问题是timeCreate不确定是唯一的还是单调增加的。如果你只有微秒分辨率,System.nanoTime()可以产生1000次以上的相同值。

private static final AtomicLong TIME_ID = new AtomicLong(0);
private static long generateTimeId() {
    long now = System.currentTimeMillis() * 1000000;
    long id = TIME_ID.getAndIncrement();
    if (id > now)
        return id;
    TIME_ID.compareAndSet(id+1, now);
    return TIME_ID.getAndIncrement();
}

// produce a monotonically increasing time id.
private final long timeCreate = generateTimeId();
private final int hashCode = (int)((timeCreate >> 32) ^ timeCreate);

注意:如果两个对象等于== true,则它们必须具有相同的hashCode。

答案 1 :(得分:0)

通常哈希码是根据对象的状态确定的,如果在计算哈希码时不考虑对象的状态,则需要处理hashcode()equals()关系

答案 2 :(得分:0)

你在做什么并不是真的和contract for hashCode坐在一起。

在你的系统中,除非两个对象完全同时创建,否则它们没有相同的hashCode,所以你也可以使用Object类的默认实现,它认为两个对象是如果它们是不同的实例(这就是这里发生的事情),则会有所不同。

如果这是你想要的,我会删除那个自定义代码......