1

在 Guava 的 ImmutableMap 的 javadocs 中它说:

性能说明:与 HashMap 不同,ImmutableMap 没有针对具有慢 Object.equals(java.lang.Object) 或 Object.hashCode() 实现的元素类型进行优化。您可以通过让元素类型缓存其自己的哈希码并利用缓存的值来缩短慢速等于算法,从而获得更好的性能。

所以我的第一个问题是我如何知道我的元素是否具有缓慢的 .equals 或 .hashCode 实现?在我的具体实例中,我使用 java Enum 作为我的键,因此它具有 .equals 和 .hashCode 的有效默认实现,对吗?(我假设这些值的实现是无关紧要的,只要您不使用值的值访问地图。)

我的第二个问题是“让你的元素类型缓存它自己的哈希码”是什么意思!谷歌搜索我似乎无法找到你如何做到这一点的例子。我想这可能意味着您最终会在哈希码中使用哈希码?所以我进入哈希码桶,然后 .equals 方法在其中使用第二组哈希码?

4

3 回答 3

4

我使用 java Enum 作为我的键,因此它具有 .equals 和 .hashCode 的有效默认实现,对吗?

equals 或 hashcode 都没有被覆盖,因此它几乎不可能更快(即 equals 返回this == other)。

我的第二个问题是“让你的元素类型缓存它自己的哈希码”是什么意思!

你可以有类似下面的代码,以避免多次计算 - 如果你这样做,你需要确保:

  • 哈希码是不变的(即不能在实例的整个生命周期内改变)
  • 您的hashcode方法是线程安全的(例如,可以使用局部变量或更简单地通过使hashvolatile 来完成)。
class MyClass {
    private int hash;

    public int hashcode() {
        int hash = this.hash;
        if (hash == 0) {
            hash = calculateIt();
            this.hash = hash;
        }
        return hash;
    }
}
于 2013-03-16T21:20:57.233 回答
2

如果您的密钥是一个,Enum那么这对您来说不是问题。

他们谈论的缓存哈希码是这样的:

private volatile int hashCode = -1;

@Override
public int hashCode() {
  if ( hashCode == -1 ) {
    hashCode = longCalculation();
  }
  return hashCode;
}
于 2013-03-16T21:20:03.600 回答
0

EnumpMap我知道这是一个非常古老的问题,但对于像我一样来到这里的人 -如果您的密钥是枚举,您真的应该使用。

于 2018-05-11T19:05:27.860 回答