Joshua Bloch在有效的java中建议如何在Java中使用缓存哈希码?

bra*_*orm 7 java caching hashcode effective-java

我有以下来自Joshua Bloch的有效Java代码(第9章,第3章,第49页)

如果类是不可变的并且计算哈希代码的成本很高,您可以考虑在对象中缓存哈希代码,而不是每次请求时重新计算它.如果您认为此类型的大多数对象将用作哈希键,则应在创建实例时计算哈希码.否则,您可能会在第一次调用hashCode时选择懒惰地初始化它(Item 71).目前尚不清楚我们的PhoneNumber类是否值得这样做,只是为了向您展示它是如何完成的:

    // Lazily initialized, cached hashCode
    private volatile int hashCode;  // (See Item 71)
    @Override public int hashCode() {
        int result = hashCode;
        if (result == 0) {
            result = 17;
            result = 31 * result + areaCode;
            result = 31 * result + prefix;
            result = 31 * result + lineNumber;
            hashCode = result;
        }
        return result;
    }
Run Code Online (Sandbox Code Playgroud)

我的问题是如何缓存(记住hashCode)在这里工作.第一次hashCode()调用方法,没有hashCode将其分配给结果.这个缓存如何工作的简要解释将是伟大的.谢谢

Ami*_*ani 10

简单.阅读下面的嵌入式评论......

private volatile int hashCode;
//You keep a member field on the class, which represents the cached hashCode value

   @Override public int hashCode() {
       int result = hashCode;
       //if result == 0, the hashCode has not been computed yet, so compute it
       if (result == 0) {
           result = 17;
           result = 31 * result + areaCode;
           result = 31 * result + prefix;
           result = 31 * result + lineNumber;
           //remember the value you computed in the hashCode member field
           hashCode = result;
       }
       // when you return result, you've either just come from the body of the above
       // if statement, in which case you JUST calculated the value -- or -- you've
       // skipped the if statement in which case you've calculated it in a prior
       // invocation of hashCode, and you're returning the cached value.
       return result;
   }
Run Code Online (Sandbox Code Playgroud)

  • @Charan它根本没有必要(如果你看一下`java.lang.String`源,`hash`字段不是`volatile`.不使它变为volatile的唯一缺点是在不同的CPU上运行的线程可能会多次重新计算哈希码.但是因为字符串在java中是不可变的,所以不会导致任何不一致,只是可能的性能损失,我想这是可以的,因为哈希的读取方式比计算的更频繁(和易失性)与正常读取相比,读取可能具有显着的开销). (5认同)