2016-04-11 60 views
5
/** 
    * Computes key.hashCode() and spreads (XORs) higher bits of hash 
    * to lower. Because the table uses power-of-two masking, sets of 
    * hashes that vary only in bits above the current mask will 
    * always collide. (Among known examples are sets of Float keys 
    * holding consecutive whole numbers in small tables.) So we 
    * apply a transform that spreads the impact of higher bits 
    * downward. There is a tradeoff between speed, utility, and 
    * quality of bit-spreading. Because many common sets of hashes 
    * are already reasonably distributed (so don't benefit from 
    * spreading), and because we use trees to handle large sets of 
    * collisions in bins, we just XOR some shifted bits in the 
    * cheapest possible way to reduce systematic lossage, as well as 
    * to incorporate impact of the highest bits that would otherwise 
    * never be used in index calculations because of table bounds. 
    */ 

static final int hash(Object key) { 
    int h; 
    return (key == null) ? 0 : (h = key.hashCode())^(h >>> 16); 
} 

sotto è la versione precedente di JDK 1,6metodo comprensione commento per hash() della classe HashMap in Java 8

/** 
    * Applies a supplemental hash function to a given hashCode, which 
    * defends against poor quality hash functions. This is critical 
    * because HashMap uses power-of-two length hash tables, that 
    * otherwise encounter collisions for hashCodes that do not differ 
    * in lower bits. Note: Null keys always map to hash 0, thus index 0. 
    */ 
    static int hash(int h) { 
     // This function ensures that hashCodes that differ only by 
     // constant multiples at each bit position have a bounded 
     // number of collisions (approximately 8 at default load factor). 
     h ^= (h >>> 20)^(h >>> 12); 
     return h^(h >>> 7)^(h >>> 4); 
    } 

qualcuno può spiegare quali sono i vantaggi di questo che applicano questo tipo di hashing di quanto non è stato fatto nelle versioni precedenti di Java. In che modo ciò inciderà sulla velocità e sulla qualità della distribuzione delle chiavi e mi riferisco alla nuova funzione di hash implementata in jdk 8 e al modo in cui è stata raggiunta per ridurre le collisioni?

+1

Potrebbe includere uno snippet di codice su come è stato eseguito nelle versioni precedenti? In particolare, potrebbero esserci implementazioni diverse in diverse versioni. Quale intendi esattamente? –

+0

http://stackoverflow.com/questions/30225054/why-is-there-a-transformation-of-hashcode-to-get-the-hash-and-is-it-a-good-idea e http://stackoverflow.com/questions/33177043/why-and-how-does-hashmap-have-its-own-internal-implementation-of-hashcode-call/33177236 – Tom

+0

@tobias_k ha modificato la domanda per includere la versione precedente dell'hash. –

risposta

2

In situazioni in cui il metodo hashCode si comporta in modo abbastanza grave, le prestazioni di HashMap possono degradare notevolmente. Ad esempio, supponiamo che il tuo metodo hashCode abbia generato solo un numero di bit 16.

Questo risolve il problema con xor il codice hash con se stesso spostato a destra 16. Se il numero fosse ben distribuito prima di questo dovrebbe ancora essere. Se fosse male, questo dovrebbe migliorarlo.

+0

Ma come siamo arrivati ​​allo spostamento di 16 bit a destra e perché no 32 lo rende efficiente. Vuoi sapere come abbiamo circolato su questo –