Guava ImmutableMap中的性能警告

时间:2013-03-16 21:15:17

标签: java guava

在Guava的ImmutableMap的javadoc中,它说:

  

性能说明:与HashMap不同,ImmutableMap未针对   具有较慢Object.equals(java.lang.Object)或。的元素类型   Object.hashCode()实现。你可以获得更好的表现   让你的元素类型缓存自己的哈希码,并通过使用   等待缓存等于慢速等于算法的缓存值。

所以我的第一个问题是如何知道我的元素是否有慢的.equals或.hashCode实现?在我的特定实例中,我使用java Enum作为我的密钥,因此它具有.equals和.hashCode的有效默认实现,对吧? (我假设只要您没有使用值的值访问地图,那么值的实现就无关紧要了。)

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

3 个答案:

答案 0 :(得分:4)

  

我使用java Enum作为我的密钥,因此有一个有效的.equals和.hashCode默认实现,对吗?

无论是equals还是hashcode都没有被覆盖,所以它几乎不会快得多(即等于返回this == other)。

  

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

您可以使用下面的代码,以避免多次计算 - 如果您这样做,您需要确保:

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

    public int hashcode() {
        int hash = this.hash;
        if (hash == 0) {
            hash = calculateIt();
            this.hash = hash;
        }
        return hash;
    }
}

答案 1 :(得分:2)

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

他们谈论缓存哈希码的方式如下:

private volatile int hashCode = -1;

@Override
public int hashCode() {
  if ( hashCode == -1 ) {
    hashCode = longCalculation();
  }
  return hashCode;
}

答案 2 :(得分:0)

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