2012-03-19 11 views
10

Ho bisogno di avere la possibilità di avere oggetti unici in una collezione.È un HashSet <T> uguale all'Elenco <T> ma con univocità?

Stavo per usare un dizionario in modo da poter usare il metodo ContainsKey ma pensavo che sarebbe stato uno spreco perché non avrei usato la proprietà Value della coppia Key/Value.

Mi sono imbattuto nel HashSet<T> che sembra molto promettente. L'unica cosa che posso trovare che non riesco a trovare nei documenti List<T> è che HashSet<T> non è ordinato. Penso che vada bene, presumo significhi che non è ordinato usando un IEqualityComparer. Finché l'ordine in cui vengono aggiunti gli articoli si trova nella stessa posizione dell'indice, penso che sarà ok poiché devo fare il controllo duplicato da cui deriva l'hashset e quindi controllare che tutte le voci siano sequenziali.

C'è qualcos'altro che mi è mancato confrontando i due tipi?

+0

possibile duplicato di [Qual è la differenza tra HashSet e Lista in C#?] (Http://stackoverflow.com/questions/6391738/what-is-the-difference-between-hashsett-and-listt- in-c) – nawfal

risposta

20

No, è importante sottolineare che lo HashSet<T> non ha alcun concetto di ordinamento o indicizzazione: un elenco ha concettualmente slot 0 .... n-1, mentre un set è "solo un set".

Penso che vada bene, presumo significhi che non è ordinato utilizzando unComponente IEquality.

IEqualityComparer non viene utilizzato per ordinare in ogni caso - IT solo parla di codici di uguaglianza e di hash. HashSet<T> non è ordinato da o un confronto di elementi (come, ad esempio, SortedSet<T> è) o ordine di inserzione.

Fintantoché l'ordine di aggiunta degli articoli si trova nella stessa posizione di indice, penso che sarà ok.

Ci è nessuna posizione di indice, e quando eseguire iterazioni su una HashSet<T> non c'è alcuna garanzia che otterrà indietro nell'ordine in cui sono stati aggiunti. Se sei anche a a proposito di ordinare , il numero HashSet<T> non è quello che cerchi.

Ancora una volta, tutto questo è anche true di Dictionary<TKey, TValue> - non si dovrebbe fare alcuna ipotesi su come ordinare lì.

+0

Quindi esiste un elenco unico disponibile ovunque? – Jon

+2

@Jon: No, ma potresti scriverne uno. Potrebbe potenzialmente essere supportato da un 'Elenco ' per ordinare * e * un 'HashSet ' per l'unicità. –

+1

@Jon - Non è perfetto ma "OrderedDictionary" mantiene l'ordine inserito e ti offre anche ricerche veloci basate sui tasti ... http://msdn.microsoft.com/en-us/library/system.collections.specialized. ordereddictionary.aspx Non è una collezione generica, che tipo di schifo. E il parametro Value sarebbe uno spreco nel tuo caso. –

6

No. A HashSet non consente l'accesso tramite indice perché gli articoli non sono ordinati. Questo significa che non significa, come sospetti, che non sono ordinati secondo lo IEqualityComparer. Significa che sono non memorizzati all'interno dell'hash set nell'ordine di aggiunta.

Quindi, se avete bisogno di un contenitore di conservazione ordine o casuale, HashSet non fa per voi.

+0

Ho aggiornato la mia domanda per spiegare che ho bisogno di una collezione così posso verificare la presenza di duplicati e quindi assumendo che l'ordine sia mantenuto devo controllare che tutti i valori siano sequenziali. – Jon

1

Hai sbagliato leggermente. Né DictionaryHashSet conserva l'ordine degli articoli, questo significa che non è possibile fare affidamento sull'indice dell'oggetto. In teoria è possibile utilizzare LINQ ElementAt() per accedere all'elemento per indice, ma ancora entrambe le raccolte non garantiscono che l'ordine venga mantenuto.

.NET fornisce una classe OrderedDictionary, ma non è generica in modo da non avere un tipo di sicurezza in fase di compilazione. In ogni caso consente l'accesso agli oggetti per indice.

Ecco una implementazione personalizzata di quella generica: OrderedDictionary(of T): A generic implementation of IOrderedDictionary. Il punto chiave: persiste due raccolte - List e Dictionary allo stesso tempo; Elenco fornisce l'accesso per indice e Dictionary fornisce l'accesso rapido da una chiave.

+0

Ho aggiornato la mia domanda per spiegare che ho bisogno di una collezione così posso controllare i duplicati e quindi supponendo che l'ordine sia mantenuto, devo controllare che tutti i valori siano sequenziali. – Jon

+1

@Jon: dai un'occhiata alla classe OrderedDictionary – sll

1

Bene HashSet concettualmente è un List di valori univoci, ma nella differenza da List<T> in realtà non implementa l'interfaccia IList, ma implementa ICollection. in più ha una serie di funzioni speciali, come:

Intersection, IsSubsetOf, IsSupersetOf, Union, che List<T> non hai.

Queste funzioni, naturalmente, sono utili nelle operazioni su più HasSet s.

2

Sembra che questo è ciò che stai dopo:

class UniqueList<T> : Collection<T> 
{ 
    protected override void InsertItem(int index, T item) 
    { 
     if (!base.Contains(item)) 
     { 
      base.InsertItem(index, item); 
     } 
     else 
     { 
      // whatever 
     } 
    } 
} 

Calling UniqueList.Add aggiungerà un elemento alla fine della lista, e non aggiungerà valori duplicati.

9

Si tratta di un 'immagine' di quello che una List<T> assomiglia:

List: |a|b|r|t|i|p|c|y|z|... 
Index: |0|1|2|3|4|5|6|7|8|... 

Il List<T> rappresenta, così, un elenco di elementi. È possibile fare riferimento a un articolo in base alla sua posizione nell'elenco.

Si tratta di un 'immagine' di quello che una HashSet<T> assomiglia:

Set: |a|b|c| | | | | |i| | | | | | |p| |r| |t| | | | |y|z| 
Bucket: |a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z| 

Il HashSet<T> rappresenta un insieme di oggetti unici. Ogni oggetto ha il suo "secchio". È possibile fare riferimento a un articolo dal relativo bucket. Il bucket a cui un elemento appartiene viene calcolato direttamente da un oggetto.

Uno dei vantaggi dell'utilizzo di HashSet su un List è la ricerca in tempo costante. In un List, un elemento può trovarsi ovunque nello List, quindi per trovarlo, è necessario esaminare ogni elemento nello List. In un HashSet, c'è solo una posizione possibile per ogni dato elemento. Pertanto, per cercare un oggetto, tutto ciò che devi fare è cercare nel suo secchio. Se è lì, è lì, se non lo è, non lo è.

Le illustrazioni potrebbero non essere accurate al 100% (per ragioni di semplicità). Soprattutto l'esempio HashSet.

Problemi correlati