HashSet e unicità
Tenga traccia dei valori distinti.
HashSet e unicità è una lezione C# Academy gratuita su CoddyKit. Questa è la lezione 3 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento C# Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso C# Academy include 4 lezioni in totale.
Che cos'è un HashSet?
HashSet<T> memorizza una raccolta di valori univoci, senza duplicati. L'aggiunta di un valore già presente non produce alcun effetto.
Come un dizionario, si basa su una tabella hash, quindi i controlli di appartenenza hanno complessità media O(1). Non mantiene l'ordine di inserimento.
using System.Collections.Generic;
var seen = new HashSet<int>();
seen.Add(1);
seen.Add(1); // ignored, still one elementAdd restituisce un booleano
Add restituisce true se il valore era nuovo e false se era già presente.
Questo valore restituito è utile per rilevare i duplicati in un unico passaggio, senza un controllo separato con Contains.
using System;
using System.Collections.Generic;
class Program {
static void Main() {
var set = new HashSet<string>();
Console.WriteLine(set.Add("a")); // True
Console.WriteLine(set.Add("a")); // False
}
}Controlli rapidi di appartenenza
Contains su un HashSet ha complessità media O(1), rispetto a O(n) su una List.
Quando chiede ripetutamente «ho già visto questo valore?», un set è lo strumento giusto. La differenza di velocità aumenta notevolmente quando la raccolta diventa grande.
using System;
using System.Collections.Generic;
class Program {
static void Main() {
var ids = new HashSet<int> { 10, 20, 30 };
Console.WriteLine(ids.Contains(20)); // True
Console.WriteLine(ids.Contains(99)); // False
}
}Rimozione dei duplicati da una lista
Un'attività comune consiste nel prendere una lista e conservare solo i valori distinti. La costruzione di un HashSet a partire dalla lista svolge questa operazione in O(n).
Il set risultante contiene ogni valore una sola volta. Se le serve nuovamente una lista, la avvolga così: new List<int>(set).
using System;
using System.Collections.Generic;
class Program {
static void Main() {
var nums = new List<int> { 1, 2, 2, 3, 3, 3 };
var unique = new HashSet<int>(nums);
Console.WriteLine(unique.Count); // 3
}
}Unione
UnionWith aggiunge ogni elemento di un'altra raccolta, ignorando i duplicati. Il risultato contiene tutti gli elementi di entrambe.
Questa operazione modifica direttamente il set. È molto più pulita rispetto a un ciclo che chiama Add manualmente per ogni elemento.
using System;
using System.Collections.Generic;
class Program {
static void Main() {
var a = new HashSet<int> { 1, 2, 3 };
a.UnionWith(new[] { 3, 4, 5 });
Console.WriteLine(a.Count); // 5
}
}Intersezione
IntersectWith conserva solo gli elementi presenti anche nell'altra raccolta e rimuove tutti gli altri.
La utilizzi per trovare gli elementi comuni, ad esempio i tag condivisi da due articoli o gli utenti appartenenti a entrambi i gruppi.
using System;
using System.Collections.Generic;
class Program {
static void Main() {
var a = new HashSet<int> { 1, 2, 3, 4 };
a.IntersectWith(new[] { 2, 4, 6 });
Console.WriteLine(string.Join(",", a)); // 2,4
}
}Differenza
ExceptWith rimuove dal set ogni elemento presente nell'altra raccolta, lasciando quelli esclusivi del set.
È l'operazione di differenza tra insiemi: «gli elementi in A ma non in B». È ideale per calcolare che cosa è cambiato o che cosa resta da elaborare.
var a = new HashSet<int> { 1, 2, 3, 4 };
a.ExceptWith(new[] { 2, 4 });
// a now contains 1 and 3Sottoinsieme e sovrainsieme
IsSubsetOf e IsSupersetOf verificano le relazioni di contenimento tra set e restituiscono un bool.
Overlaps verifica se è condiviso almeno un elemento, mentre SetEquals controlla se due set contengono esattamente gli stessi elementi, indipendentemente dall'ordine.
var a = new HashSet<int> { 1, 2 };
var b = new HashSet<int> { 1, 2, 3 };
bool sub = a.IsSubsetOf(b); // true
bool ov = a.Overlaps(b); // trueUguaglianza degli elementi
L'unicità dipende da GetHashCode e Equals del tipo degli elementi, esattamente come per le chiavi dei dizionari.
Per i tipi personalizzati, esegua l'override di entrambi i metodi oppure utilizzi un record; in caso contrario, due oggetti logicamente uguali vengono trattati come distinti e finiscono entrambi nel set.
var names = new HashSet<string>(
System.StringComparer.OrdinalIgnoreCase);
names.Add("Sam");
bool dup = !names.Add("SAM"); // true: treated as sameNessun indice né ordine
Un HashSet non consente l'accesso tramite indice: non può scrivere set[0]. Può solo enumerarlo con foreach.
L'ordine di enumerazione non è garantito. Se le servono sia l'unicità sia l'ordine ordinato, utilizzi SortedSet<T>, che mantiene gli elementi ordinati al costo di operazioni O(log n).
using System;
using System.Collections.Generic;
class Program {
static void Main() {
var s = new SortedSet<int> { 3, 1, 2 };
Console.WriteLine(string.Join(",", s)); // 1,2,3
}
}Tracciamento degli elementi già visti
Un modello frequente consiste nel filtrare un flusso in modo che ogni valore compaia una sola volta. Aggiunga ogni valore a un set e agisca solo quando Add restituisce true.
È più pulito e veloce che controllare una lista in continua crescita, trasformando una scansione O(n al quadrato) in O(n).
using System;
using System.Collections.Generic;
class Program {
static void Main() {
var seen = new HashSet<int>();
foreach (int x in new[] { 1, 1, 2, 3, 2 })
if (seen.Add(x)) Console.Write(x + " ");
// prints 1 2 3
}
}Verifica rapida
Ricordi quali vincoli impone un HashSet e qual è il costo delle sue ricerche.
Riepilogo
HashSet<T> memorizza valori univoci e offre, in media, operazioni O(1) di aggiunta, rimozione e controllo di appartenenza, ma non supporta ordine né indicizzazione.
È particolarmente utile per rimuovere duplicati, verificare rapidamente «ho già visto questo valore?» e applicare operazioni tra insiemi tramite UnionWith, IntersectWith ed ExceptWith. I tipi di elemento personalizzati richiedono una corretta implementazione dell'uguaglianza.
Domande Frequenti
La lezione «HashSet e unicità» è gratuita?
Sì — il testo completo di «HashSet e unicità» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso C# Academy, passa a CoddyKit PRO. Il corso C# Academy include 4 lezioni in totale.
Cosa imparerò in «HashSet e unicità»?
Tenga traccia dei valori distinti. Eserciti C# Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare C# Academy?
Non è richiesta alcuna esperienza precedente. C# Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 3 di 4.
Quanto tempo richiede la lezione «HashSet e unicità»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione C# Academy?
Sì. Ogni lezione C# Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Le liste nella pratica
- Ricerche nei dizionari
- HashSet e unicità
- Scegliere una collezione