how caching hashcode works in Java as suggested by Joshua Bloch in effective java?

前端 未结 3 1611
旧巷少年郎
旧巷少年郎 2020-12-14 04:53

I have the following piece of code from effective java by Joshua Bloch (Item 9, chapter 3, page 49)

If a class is immutable and the cost of computing

相关标签:
3条回答
  • 2020-12-14 05:21

    If you really wanted this to work right, you'd put another volatile variable boolean called isHashInvalid. Every setter involving values accessed in your hash function would set this variable. Then it becomes, (no need to test for '0' now):

    private volatile int isHashInvalid=TRUE;
    private volatile int hashCode; //Automatically zero but it doesn't matter
    
    //You keep a member field on the class, which represents the cached hashCode value
    @Override public int hashCode() {
        int result = hashCode;
        if (isHashInvalid) {
           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;
           isHashInvalid=FALSE;
        }
        // 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;
    }
    
    0 讨论(0)
  • 2020-12-14 05:23

    Simple. Read my embedded comments below...

    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;
       }
    
    0 讨论(0)
  • 2020-12-14 05:28

    The hashCode variable in an instance variable, and it's not initialized explicitly, so Java intializes it to 0 (JLS Section 4.12.5). The comparison result == 0 is in effect a check to see if result has been assigned a presumably non-zero hash code. If it hasn't been assigned yet, then it performs the calculation, else it just returns the previously computed hash code.

    0 讨论(0)
提交回复
热议问题