Explanation of HashMap#hash(int) method

后端 未结 2 1366
余生分开走
余生分开走 2020-12-01 07:58

Can someone please explain to me the static HashMap#hash(int) method?

What\'s the justification behind it to generate uniformly distributed hashes?

/         


        
2条回答
  •  死守一世寂寞
    2020-12-01 08:41

    >>> is the logical right shift (no sign-extension) (JLS 15.19 Shift Operators), and ^ is the bitwise exclusive-or (JLS 15.22.1 Integer Bitwise Operators).

    As to why this is done, the documentation offers a hint: HashMap uses power-of-two length tables, and hashes keys by masking away the higher bits and taking only the lower bits of their hash code.

    // HashMap.java -- edited for conciseness
    static int indexFor(int h, int length) {
        return h & (length-1);
    }
    
    public V put(K key, V value) {
        int hash = hash(key.hashCode());
        int index = indexFor(hash, table.length);
        // ...
    }
    

    So hash() attempts to bring relevancy to the higher bits, which otherwise would get masked away (indexFor basically discards the higher bits of h and takes only the lower k bits where length == (1 << k)).

    Contrast this with the way Hashtable (which should have NOT a power-of-two length table) uses a key's hash code.

    // Hashtable.java -- edited for conciseness
    public synchronized V get(Object key) {
        int hash = key.hashCode();
        int index = (hash & 0x7FFFFFFF) % table.length;
        // ...
    }
    

    By doing the more expensive % operation (instead of simple bit masking), the performance of Hashtable is less sensitive to hash codes with poor distribution in the lower bits (especially if table.length is a prime number).

提交回复
热议问题