Java Apache Commons哈希代码生成器不一致哈希

Java Apache Commons哈希代码生成器不一致哈希,java,hashcode,apache-commons-lang3,Java,Hashcode,Apache Commons Lang3,我将哈希代码生成器用作pojo的实例变量 public class Pojo { private HashCodeBuilder hashBuilder = new HashCodeBuilder(); private int i; public setI(int i) {this.i = i} @Override public int hashCode() { hashBuilder.append(id); return hashBui

我将哈希代码生成器用作pojo的实例变量

public class Pojo {
private HashCodeBuilder hashBuilder = new HashCodeBuilder(); 
private int i;
public setI(int i) {this.i = i}

@Override
public int hashCode() {           
    hashBuilder.append(id);        
    return hashBuilder.toHashCode();
}
}
现在,如果我将
I
的值设置为相同的值两次,那么hashcode结果将不同。这是实现中的一个bug吗

我知道这是因为散列代码生成器保持一个运行总数。但它是否应该为同一组值提供相同的哈希值

此外,如果我不遵循上述方法,那么我将在我的pojo的
hashcode
方法中初始化相同的哈希代码生成器数千次,如下所示:

...
@Override
public int hashCode() {   
    hashBuilder = new HashBuilder();        
    hashBuilder.append(id);        
    return hashBuilder.toHashCode();
}
...

是否有办法重置此运行总数,以便每次我使用相同的值集调用
hashcode
,我都能得到一致的答案?

您这样做的方式是在每次调用
hashcode()
时追加另一个
id
。由于
append()
正在接受一个值(而不是字段名!),因此
HashCodeBuilder
无法知道您是将
id
追加了两次,还是有另一个字段中的值相同

hashCode()
中本地创建
HashCodeBuilder
。不要认为它会对性能产生重大影响,除非您已经分析了应用程序并证明它确实会影响性能(也就是说,避免过早优化)


如果确实希望避免在每个
hashCode()
上不必要地创建
HashCodeBuilder
,则必须跟踪setter中的更改,并在通过setter更改值时将
HashCodeBuilder
设置为
null
;如果需要,请在
hashCode()
中使用它。然后,您必须确保所有字段修改都通过setter。很多工作和很多事情都可能出错,因此如果可能,您确实希望避免所有这些。

为什么重置比创建新实例更有效?首先,你不应该重复使用它。它甚至会使用相同的id失败,并连续调用两次
hashCode
。您将得到
X
哈希代码生成器对象,这些对象可能会被垃圾收集,但您永远不知道何时会发生。因此,在此之前,您的内存使用率将增加。所以我认为最好只有一个pojo?不,不是。特别是对于寿命短的对象,它们或多或少是免费的。他们很快就被干掉了。看起来是过早的优化,而不是真正的测量结果。嗯,那么我假设多次调用它不会产生任何副作用-感谢您的澄清,或者简单的解决方案是在哈希生成器中提供重置方法?显然,库作者认为不需要这种方法。在Java中创建一次性实例的成本很低。实例变量影响线程安全。通常的用法是只在本地将实例保存在
hashCode()
中,如果您想进行哈希代码缓存,最好缓存生成的哈希代码,而不是保存生成器。更新-我刚刚通读了生成器实现,使用了threadlocal,因此线程安全不会成为问题。