HashSet<T> in .NET 9

Cos’è un HashSet<T>?

In .NET, un HashSet<T> è una collezione che implementa un set non ordinato di elementi unici. Introdotto con la libreria delle collezioni generiche in NET Framework 3.5 , HashSet<T> beneficia di ulteriori ottimizzazioni per prestazioni, grazie a miglioramenti nell’implementazione interna del framework e possiamo paragonarlo ad un Dizionario dove la chiave è un hash (generato automaticamente) ed il valore è quando gli abbiamo inserito.

Nella programmazione di tutti i giorni andiamo ad utilizzarlo nei casi in cui necessitiamo di una lista i cui elementi devono essere unici. I suoi benefici sono sopratutto

  • Prestazioni: Grazie all’uso di una tabella hash, le operazioni comuni come Contains hanno una complessità temporale O(1) nella maggior parte dei casi (a differenza delle stringhe che hanno una complessità O(n), poiché la lista deve scansionare tutti gli elementi esistenti).
  • Univocità: Ideale per collezioni di dati dove è necessario evitare duplicati senza ulteriori verifiche manuali. I duplicati vengono automaticamente eliminati

Vediamo ora alcuni casi pratici per capire meglio il suo funzionamento:

Creazione

Vediamo diversi modi per istanziare un oggetto di tipo HashSet<T>, nei primi casi passando nel costruttore una lista già esistente, nel secondo aggiungendo elementi man mano.

C#
var stringList = new List<string> { "Alice", "Bob", "Giorgio" };
var hashSet1 = new HashSet<string>(stringList);

var intList = new List<int> { 1, 2, 3, 4, 5 };
var hashSet2 = new HashSet<int>(intList);

var hashSet3 = new HashSet<int>();
hashSet3.Add(1);
hashSet3.Add(2);
hashSet3.Add(3);
hashSet3.Add(4);

Unione di due liste di HashSet<T>

C#
var hashSet1 = new HashSet<int>(new List<int> { 1, 2, 3, 4, 5 });
var hashSet2 = new HashSet<int>(new List<int> { 5, 6, 7, 8, 9 });

hashSet1.UnionWith(hashSet2);

foreach (var item in hashSet1)
{
    Console.WriteLine(item);
}

/*
Output:

1
2
3
4
5
6
7
8
9

*/

Intersezione di due liste

Per trovare gli elementi in comune

C#
var hashSet1 = new HashSet<int>(new List<int> { 1, 2, 3, 4, 5 });
var hashSet2 = new HashSet<int>(new List<int> { 3, 4, 5, 6, 7 });

hashSet1.IntersectWith(hashSet2);

foreach (var item in hashSet1)
{
    Console.WriteLine(item);
}

/*
Output:

3
4
5

*/

Subset (ExceptWith)

In questo esempio vediamo come ritornare un HashSet<T> rimuovendo gli elementi presenti un secondo HashSet<T>:

C#
var hashSet1 = new HashSet<int>(new List<int> { 1, 2, 3, 4, 5 });
var hashSet2 = new HashSet<int>(new List<int> { 3, 4, 5, 6, 7 });

hashSet1.ExceptWith(hashSet2);

foreach (var item in hashSet1)
{
    Console.WriteLine(item);
}

/*
Output:

1
2

*/

Eliminazione dei duplicati

Quando viene inizializzato l’oggetto HashSet<T> con la lista di stringhe verranno automaticamente eliminati i doppioni (Alice è presente 3 volte). Da notare che è presente “Bob” e “bob”.

C#
var list = new List<string> { "Alice", "Bob", "Alice", "Alice", "Giorgio", "bob" };
var hashSet = new HashSet<string>(list);

foreach (var item in hashSet)
{
    Console.WriteLine(item);
}

/*
Output:

    Alice
    Bob
    Giorgio
    bob
    
*/

Conclusioni

HashSet<T> è uno strumento potente, ad alte prestazioni e versatile per gestire collezioni di dati univoci in .NET. Grazie alle sue caratteristiche e al supporto per operazioni sui set, può semplificare molti scenari complessi migliorando le prestazioni.

Condividi questo articolo
Shareable URL
Post precedente

Principio di programmazione SOLID

Prosimo post

Salvataggio delle password nel database

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Leggi il prossimo articolo