Molti libri e tutorial dicono che la dimensione di una tabella hash deve essere un numero primo per distribuire uniformemente le chiavi in tutti i bucket. Ma Java HashMap
utilizza sempre una dimensione che è una potenza di due. Non dovrebbe usare un numero primo? Cosa c'è di meglio, un "primo" o un "potere di due" come dimensione della tabella hash?Java: un numero "primo" o una "potenza di due" come dimensione HashMap?
risposta
Utilizzando una potenza di due maschere efficacemente i bit più in alto del codice hash. Pertanto, in questo scenario, una funzione di hash di scarsa qualità potrebbe rivelarsi particolarmente negativa.
di Java HashMap
mitiga questo di diffidare hashCode()
implementazione dell'oggetto e applying a second level of hashing to its result:
applica una funzione di hash supplementare per un dato hashCode, che difende contro poveri funzioni hash qualità. Questo è fondamentale perché HashMap utilizza tabelle hash power-of-two, che altrimenti incontrano collisioni per hashCode che non differiscono in bit inferiori.
Se si dispone di una buona funzione di hash, o fare qualcosa di simile a quello che HashMap
fa, non importa se si utilizza numeri primi ecc come la dimensione della tabella.
Se, d'altra parte, la funzione di hash è di scarsa qualità o sconosciuta, utilizzare un numero primo sarebbe una scommessa più sicura. Tuttavia, renderà le tabelle dinamicamente più difficili da implementare, poiché all'improvviso sarà necessario essere in grado di produrre numeri primi invece di moltiplicare le dimensioni per un fattore costante.
Per curiosità: perché? (o avete riferimenti/collegamenti che spieghino questo)? –
+1 per l'aggiornamento –
Sei sicuro che la dimensione della tabella non sia importante? Non è il punto di una buona funzione di hash per diffondere i dati attraverso la tabella, al fine di ridurre il numero di collisioni? Ma se la tabella è molto piccola, le collisioni aumenteranno, indipendentemente dalla funzione hash. Mi sto perdendo qualcosa? – pamphlet
L'implementazione HashMap standard ha un metodo hash
che rielabora l'hashcode dell'oggetto per evitare quel trabocchetto. Il commento prima the hash()
method legge:
/**
* Retrieve object hash code and applies a supplemental hash function to the
* result hash, 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.
*/
Dal punto puntualità/calcolo di vista potenze di due dimensioni possono essere calcolati con solo bit di mascheramento che è più veloce di divisione intera che sarebbe necessaria altrimenti.
L'unico modo per sapere quale è il migliore tra primo e power-of-two è quello di confrontarlo.
Molti anni fa, durante la scrittura di un assemblatore la cui performance dipendeva fortemente dalla ricerca di simboli talbe, l'ho testato utilizzando un grande blocco di identificatori generati. Anche con una mappatura ingenua, ho trovato che il power-of-two, come previsto, aveva una distribuzione meno uniforme e catene più lunghe di un numero primo di bucket di dimensioni simili. Funzionava ancora più velocemente, a causa della velocità della selezione del secchio per mascheramento dei bit.
Sospetto fortemente che gli sviluppatori di java.util non avrebbero fatto ricorso all'hashing e al power-of-two aggiuntivi senza doverli confrontare con un numero primo di bucket. È una cosa molto ovvia da fare quando si progetta una struttura dati hash.
Per questo motivo, sono sicuro che le dimensioni rehash e power-of-two offrono prestazioni migliori per le tipiche mappe di hash Java rispetto a un numero primo di bucket.
Probabilmente si dovrebbero usare tabelle hash di dimensioni primarie se si utilizza quadratic probing per la risoluzione delle collisioni. Se si dispone di una tabella di dimensioni primarie, il sondaggio quadratico colpirà metà delle voci, meno se non è un numero primo. Quindi potresti non trovare un posto adatto per archiviare la tua voce anche se il tuo hash table è meno della metà pieno. Poiché le mappe hash di Java non utilizzano il sondaggio quadratico, non è necessario utilizzare i numeri primi come dimensioni.
- 1. Simulazione di un numero senza segno con una potenza pari a due max in java
- 2. Aumentare un numero a una potenza in Java
- 3. Come mappare due array su una HashMap in Java?
- 4. Limitazione della dimensione massima di una HashMap in Java
- 5. Iterazione su una HashMap di HashMaps in Java (o Scala)
- 6. come ottenere la dimensione di una HashMap usando jstl
- 7. Come fare una potenza frazionale su BigDecimal in Java?
- 8. WebGL e la potenza di due dimensioni dell'immagine
- 9. Come trovare la potenza di un numero in SQLite
- 10. Può una matrice java essere usato come un HashMap chiave
- 11. Texture WebGL e rettangolare (potenza di due)
- 12. enumerazioni Flag senza potenza di due valori
- 13. Come faccio a verificare se un parametro template è una potenza di due?
- 14. Come verificare se il numero può essere rappresentato in prima potenza (nth root è primo o no)
- 15. significato di "potenza di 2" nell'attuazione java.util.HashMap
- 16. java collisione HashMap
- 17. Stream Java - Ordina un elenco per una hashmap di liste
- 18. valuta se un numero è potenza intera di 4
- 19. Deterministicamente controllando se un numero elevato è primo o composito?
- 20. Ricerca di un numero primo dopo un dato numero
- 21. Utilizzo di ArrayList o HashMap
- 22. Java: HashSet vs. HashMap
- 23. Perché TreeMap di Java non consente una dimensione iniziale?
- 24. Memorizzazione una HashMap all'interno di un altro HashMap miglior rendimento
- 25. Java: chiave composta in hashmap
- 26. Una mappa java può restituire una dimensione di -1?
- 27. Come posso avere una HashMap con chiavi univoche in java?
- 28. Java XStream con HashMap
- 29. Coltivare una Hashmap di vettori in Matlab
- 30. java hashmap key iteration
Dubito che in realtà lo diano esattamente, e se lo fanno loro sbagliano. Questo è solo un modo per farlo. – EJP