Cómo usar HashSet en C #

Un HashSet es una colección optimizada de elementos únicos desordenados que proporciona búsquedas rápidas y operaciones de conjuntos de alto rendimiento. La clase HashSet se introdujo por primera vez en .NET 3.5 y es parte del espacio de nombres System.Collection.Generic. Este artículo habla sobre cómo podemos trabajar con HashSets en C #.

Para trabajar con los ejemplos de código proporcionados en este artículo, debe tener Visual Studio 2019 instalado en su sistema. Si aún no tiene una copia, puede descargar Visual Studio 2019 aquí.

Crear un proyecto de aplicación de consola .NET Core en Visual Studio

En primer lugar, creemos un proyecto de aplicación de consola .NET Core en Visual Studio. Suponiendo que Visual Studio 2019 esté instalado en su sistema, siga los pasos que se describen a continuación para crear un nuevo proyecto de aplicación de consola .NET Core en Visual Studio.

  1. Inicie el IDE de Visual Studio.
  2. Haga clic en "Crear nuevo proyecto".
  3. En la ventana "Crear nuevo proyecto", seleccione "Aplicación de consola (.NET Core)" en la lista de plantillas que se muestran.
  4. Haga clic en Siguiente.
  5. En la ventana "Configure su nuevo proyecto" que se muestra a continuación, especifique el nombre y la ubicación del nuevo proyecto.
  6. Haga clic en Crear.

Esto creará un nuevo proyecto de aplicación de consola .NET Core en Visual Studio 2019. Usaremos este proyecto para trabajar con HashSet en las siguientes secciones de este artículo.

¿Qué es un HashSet?

Un HashSet, representado por la clase HashSet perteneciente al espacio de nombres System.Collections.Generic, es una colección desordenada de alto rendimiento de elementos únicos. Por lo tanto, un HashSet no está ordenado y no contiene ningún elemento duplicado. Un HashSet tampoco admite índices; solo puede usar enumeradores. Un HashSet se usa generalmente para operaciones de alto rendimiento que involucran un conjunto de datos únicos.

La clase HashSet implementa varias interfaces como se muestra a continuación:

clase pública HashSet: System.Collections.Generic.ICollection,

System.Collections.Generic.IEnumerable,

System.Collections.Generic.IReadOnlyCollection,

System.Collections.Generic.ISet,

System.Runtime.Serialization.IDeserializationCallback,

System.Runtime.Serialization.ISerializable

Dado que HashSet contiene solo elementos únicos, su estructura interna está optimizada para búsquedas más rápidas. Tenga en cuenta que puede almacenar un solo valor nulo en un HashSet. Por lo tanto, HashSet es una buena opción cuando desea una colección que contiene elementos únicos y los elementos de la colección se pueden buscar rápidamente.

Buscar un elemento en un HashSet en C #

Para buscar un elemento en un HashSet, puede utilizar el método Contains como se muestra en el fragmento de código que se proporciona a continuación:

static void Main (cadena [] argumentos)

        {

            HashSet hashSet = nuevo HashSet ();

            hashSet.Add ("A");

            hashSet.Add ("B");

            hashSet.Add ("C");

            hashSet.Add ("D");

            si (hashSet.Contains ("D"))

                Console.WriteLine ("El elemento requerido está disponible.");

            más

                Console.WriteLine ("El elemento requerido no está disponible");

            Console.ReadKey ();

        }

Los elementos HashSet son siempre únicos

Si intenta insertar un elemento duplicado en un HashSet, simplemente se ignorará, pero no se lanzará ninguna excepción en tiempo de ejecución. El siguiente fragmento de código ilustra esto.

static void Main (cadena [] argumentos)

{

   HashSet hashSet = nuevo HashSet ();

   hashSet.Add ("A");

   hashSet.Add ("B");

   hashSet.Add ("C");

   hashSet.Add ("D");

   hashSet.Add ("D");

   Console.WriteLine ("El número de elementos es: {0}", hashSet.Count);

   Console.ReadKey ();

}

Cuando ejecute el programa, la salida será como se muestra en la Figura 1.

Ahora considere el siguiente fragmento de código que ilustra cómo se eliminan los elementos duplicados:

cadena [] ciudades = nueva cadena [] {

                "Delhi",

                "Calcuta",

                "Nueva York",

                "Londres",

                "Tokio",

                "Washington",

                "Tokio"

            };

            HashSet hashSet = nuevo HashSet (ciudades);

            foreach (ciudad var en hashSet)

            {

                Console.WriteLine (ciudad);

            }

Cuando ejecute el programa anterior, se eliminarán los nombres de ciudades duplicados.

Quitar elementos de un HashSet en C #

Para eliminar un elemento de un HashSet, debe llamar al método Remove. La sintaxis del método Remove se proporciona a continuación.

public bool Eliminar (elemento T);

Si el elemento se encuentra en la colección, el método Remove elimina un elemento del HashSet y devuelve verdadero en caso de éxito, falso en caso contrario.

El fragmento de código que se proporciona a continuación ilustra cómo puede utilizar el método Remove para eliminar un elemento de un HashSet.

elemento de cadena = "D";

si (hashSet.Contains (elemento))

{

   hashSet.Remove (elemento);

}

Para eliminar todos los elementos de un HashSet, puede utilizar el método Clear.

Usar métodos de operaciones de conjuntos HashSet en C #

HashSet tiene varios métodos importantes para establecer operaciones como IntersectWith, UnionWith, IsProperSubsetOf, ExceptWith y SymmetricExceptWith.

IsProperSubsetOf

El método IsProperSubsetOf se utiliza para determinar si una instancia de HashSet es un subconjunto adecuado de una colección. Esto se ilustra en el fragmento de código que se proporciona a continuación.

HashSet setA = new HashSet () {"A", "B", "C", "D"};

HashSet setB = new HashSet () {"A", "B", "C", "X"};

HashSet setC = new HashSet () {"A", "B", "C", "D", "E"};

si (setA.IsProperSubsetOf (setC))

   Console.WriteLine ("setC contiene todos los elementos de setA.");

si (! setA.IsProperSubsetOf (setB))

   Console.WriteLine ("setB no contiene todos los elementos de setA.");

Cuando ejecute el programa anterior, debería ver el siguiente resultado en la ventana de la consola.

UniónCon

El método UnionWith se utiliza para la adición de conjuntos como se ilustra en el fragmento de código que se proporciona a continuación.

HashSet setA = new HashSet () {"A", "B", "C", "D", "E"};

HashSet setB = new HashSet () {"A", "B", "C", "X", "Y"};

setA.UnionWith (setB);

foreach (cadena str en setA)

{

   Console.WriteLine (str);

}

Cuando ejecuta el fragmento de código anterior, los elementos de setB se copian en setA. Así que setA ahora incluirá "A", "B", "C", "D", "E", "X" e "Y". 

Intersectar con 

El método IntersectWith se utiliza para representar la intersección de dos HashSets. Aquí tienes un ejemplo para entender esto.

HashSet setA = new HashSet () {"A", "B", "C", "D", "E"};

HashSet setB = new HashSet () {"A", "X", "C", "Y"};

setA.IntersectWith (setB);

foreach (cadena str en setA)

{

    Console.WriteLine (str);

}

Cuando ejecuta el programa anterior, solo los elementos comunes a los dos HashSets se mostrarán en la ventana de la consola. La salida se vería así: 

Excepto con

El método ExceptWith representa la resta de conjuntos matemáticos y es una operación O (n). Suponga que tiene dos HashSets setA y setB y especifica la siguiente declaración:

setA.ExceptWith (setB);

Esto devolvería los elementos de setA que no están presentes en setB. Entendamos esto con otro ejemplo. Considere el fragmento de código que se proporciona a continuación.

HashSet setA = new HashSet () {"A", "B", "C", "D", "E"};

HashSet setB = new HashSet () {"A", "X", "C", "Y"};

setA.ExceptWith (setB);

foreach (cadena str en setA)

{

   Console.WriteLine (str);

}

Cuando ejecute el programa anterior, los elementos "B", "D" y "E" se imprimirán en la ventana de la consola como se muestra en la Figura 5.

SimétricoExcepto Con 

El método SymmetricExceptWith se utiliza para modificar un HashSet para que contenga solo los elementos únicos de dos HashSets, es decir, los elementos que no son comunes a ambos HashSets. Considere el siguiente fragmento de código que ilustra esto.

HashSet setA = new HashSet () {"A", "B", "C", "D", "E"};

HashSet setB = new HashSet () {"A", "X", "C", "Y"};

setA.SymmetricExceptWith (setB);

foreach (cadena str en setA)

{

  Console.WriteLine (str);

}

Cuando ejecuta el código anterior, solo los elementos únicos de setA y setB, es decir, los elementos que están presentes en setA pero no en setB, y los elementos que están presentes en setB pero no en setA, se mostrarán en la ventana de la consola. como se muestra en la Figura 6.

Si bien la complejidad promedio para acceder a un elemento en una matriz es O (n), donde n representa el número de elementos en la matriz, la complejidad es solo O (1) para acceder a un elemento particular en un HashSet. Esto hace que HashSet sea una buena opción para búsquedas rápidas y para realizar operaciones de conjuntos. Puede usar una Lista si desea almacenar una colección de elementos en un orden determinado y tal vez incluir también duplicados. 

Cómo hacer más en C #:

  • Cómo usar parámetros opcionales y con nombre en C #
  • Cómo comparar el código C # usando BenchmarkDotNet
  • Cómo usar interfaces fluidas y encadenamiento de métodos en C #
  • Cómo realizar pruebas unitarias de métodos estáticos en C #
  • Cómo refactorizar objetos de Dios en C #
  • Cómo usar ValueTask en C #
  • Cómo utilizar la inmutabilidad en C
  • Cómo usar const, readonly y static en C #
  • Cómo usar anotaciones de datos en C #
  • Cómo trabajar con GUID en C # 8
  • Cuándo usar una clase abstracta frente a una interfaz en C #
  • Cómo trabajar con AutoMapper en C #
  • Cómo usar expresiones lambda en C #
  • Cómo trabajar con delegados Action, Func y Predicate en C #
  • Cómo trabajar con delegados en C #
  • Cómo implementar un registrador simple en C #
  • Cómo trabajar con atributos en C #
  • Cómo trabajar con log4net en C #
  • Cómo implementar el patrón de diseño del repositorio en C #
  • Cómo trabajar con la reflexión en C #
  • Cómo trabajar con filesystemwatcher en C #
  • Cómo realizar la inicialización diferida en C #
  • Cómo trabajar con MSMQ en C #
  • Cómo trabajar con métodos de extensión en C #
  • Cómo usar expresiones lambda en C #
  • Cuándo usar la palabra clave volátil en C #
  • Cómo usar la palabra clave yield en C #
  • Cómo implementar polimorfismo en C #
  • Cómo construir su propio programador de tareas en C #
  • Cómo trabajar con RabbitMQ en C #
  • Cómo trabajar con una tupla en C #
  • Explorando métodos virtuales y abstractos en C #
  • Cómo usar Dapper ORM en C #
  • Cómo usar el patrón de diseño flyweight en C #