2012-08-22 8 views
8

Dalle JavaDocs di HashSet:Quali costi di iterazione su un hashset dipendono anche dalla capacità della mappa di backup?

Questa classe offre prestazioni costante di tempo per le operazioni di base (aggiungere, rimuovere, contiene e dimensione), assumendo la funzione hash disperde elementi correttamente tra i secchi. L'iterazione su questo set richiede tempo proporzionale alla somma delle dimensioni dell'istanza di HashSet (il numero di elementi) più la "capacità" dell'istanza di backup HashMap (il numero di bucket). Pertanto, è molto importante non impostare capacità iniziale troppo elevata (o il fattore di carico troppo bassa) se iterazione prestazioni è importante

Perché iterazione richiede tempo proporzionale alla somma (numero di elementi in serie + capacità della mappa di supporto) e non solo al numero di elementi nel set stesso?

.

+5

Come ti iterare tutti gli elementi, senza anche iterare su tutti i secchi vuoti? – sepp2k

+0

Correlati: http://stackoverflow.com/a/11903357/829571 – assylias

+0

Puoi anche [controllare il codice] (http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/ 7-b147/java/util/HashSet.java? Av = f # 168) e approfondisci per vedere cosa succede sotto il cofano. – assylias

risposta

12

HashSet viene utilizzato utilizzando uno HashMap in cui gli elementi sono le chiavi della mappa. Poiché una mappa ha un numero definito di bucket che può contenere uno o più elementi, l'iterazione deve controllare ciascun bucket, indipendentemente dal fatto che contenga o meno elementi.

+0

quali sono i valori di quell'hashmap? – Geek

+3

@Geek poiché i valori non contano sono solo oggetti fittizi (o più precisamente, è un oggetto fittizio: 'Oggetto statico finale privato PRESENT = new Object();'). – Thomas

3

L'utilizzo di LinkedHashSet segue l'elenco "collegato" di voci in modo che il numero di spazi non sia rilevante. Normalmente non avresti un HashSet in cui la capacità è molto più del doppio delle dimensioni effettivamente utilizzate. Anche se lo fai, la scansione di un milione di voci, per lo più null non ci vuole molto tempo (millisecondi)

+2

2 ms per ogni 1 milione di null sulla mia macchina ;-) – assylias

+0

@assylias Suona bene. L'iterazione su un HashSet non sarà bella, qualunque cosa tu faccia.Davvero vuoi fare qualche ricerca o raccolta ordinata dove stai lavorando solo su poche voci se vuoi la velocità. –

0

Perché iterazione richiede tempo proporzionale alla somma (numero di elementi in set + Capacità di mappa di backup) e non solo al numero di elementi nel set stesso?

Gli elementi sono dispersi all'interno del sottostante HashMap che è sostenuta da una matrice.
Quindi non è noto quali bucket sono occupati (ma è noto quanti elementi sono totalmente disponibili).
Quindi, per iterare su tutti gli elementi tutti secchi devono essere controllati

0

Se la vostra preoccupazione è il tempo necessario per scorrere intorno al set, e si utilizza Java 6 o superiore dare un'occhiata a questa bellezza:

ConcurrentSkipListSet