【问题标题】:Apache Commons hashCode builder inconsistent hashesApache Commons hashCode builder 不一致的哈希值
【发布时间】:2017-04-27 05:40:59
【问题描述】:

我正在使用哈希码生成器作为 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 的值设置为相同的值两次,那么我的哈希码结果将会不同。这是实现中的错误吗?

我知道这是因为哈希码生成器保持运行总计。但它不应该为同一组值提供相同的哈希吗?

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

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

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

【问题讨论】:

  • 为什么重置比创建新实例更有效?恕我直言,您首先不应该重用它。它甚至会以相同的 id 并连续两次调用 hashCode 失败。
  • 好吧,你创建了一个 pojo,然后最终调用 hashcode X 次数。您最终会得到X 哈希码生成器对象,这些对象可能会被垃圾回收,但您永远不知道何时会发生这种情况。所以在那之前你的内存使用量会增加。所以我认为最好只有一个 pojo?
  • 不,不是。尤其是对于短命的物体,它们或多或少是免费的。他们被 gc'ed 很快。看起来像是过早的优化,而不是真正的测量。
  • 嗯,那么我假设调用它 X 次没有副作用 - 感谢您的澄清

标签: java hashcode apache-commons-lang3


【解决方案1】:

每次调用hashCode() 时,您都会附加另一个id。由于append() 接受一个值(不是字段名!),HashCodeBuilder 无法知道您是否附加了两次id,或者您是否有另一个字段具有相同的值。

hashCode() 中本地创建HashCodeBuilder。不要假设它会显着影响性能,除非您已经对应用程序进行了分析并证明它确实如此(也就是避免过早优化)。

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

【讨论】:

  • 或简单的解决方案是在哈希生成器中提供重置方法?
  • 显然库作者认为不需要这种方法。在 Java 中创建一次性实例很便宜。实例变量影响线程安全。常见的用法是仅将实例保存在本地 hashCode() 中,如果您想缓存哈希码,最好缓存生成的哈希码而不是保留构建器。
  • 更新 - 我刚刚通读了构建器实现,使用了 threadlocal,因此线程安全不会成为问题。
猜你喜欢
  • 2011-06-29
  • 1970-01-01
  • 1970-01-01
  • 2022-12-14
  • 2011-02-15
  • 1970-01-01
  • 2011-05-27
  • 2013-02-26
  • 2021-05-24
相关资源
最近更新 更多