Pregunta

¿Puedes explicar cuál es la diferencia entre HashSet<T> y List<T> ¿en la red?

Quizás puedas explicar con un ejemplo en qué casos HashSet<T> debe preferirse frente a List<T> ?

¿Fue útil?

Solución

A diferencia de una lista <> ...

  1. Un HashSet es una lista sin miembros duplicados.

  2. Debido a que un HashSet está restringido para contener solo entradas únicas, la estructura interna está optimizada para la búsqueda (en comparación con una lista); es considerablemente más rápido

  3. Agregar a un HashSet devuelve un valor booleano: falso si la adición falla debido a que ya existe en el conjunto

  4. Puede realizar operaciones de conjuntos matemáticos contra un Conjunto: Unión / Intersección / IsSubsetOf, etc.

  5. HashSet no implementa IList solo ICollection

  6. No puede usar índices con un HashSet, solo enumeradores.

La razón principal para usar un HashSet sería si está interesado en realizar operaciones Set.

Dados 2 conjuntos: hashSet1 y hashSet2

 //returns a list of distinct items in both sets
 HashSet set3 = set1.Union( set2 );

vuela en comparación con una operación equivalente usando LINQ.¡También es mejor escribir!

Otros consejos

Un HashSet<T> es una clase diseñada para brindarle una búsqueda de O(1) para la contención (es decir, ¿esta colección contiene un objeto en particular? Dime la respuesta rápidamente).

Un List<T> es una clase diseñada para darle una colección con acceso aleatorio O(1) que puede crecer dinámicamente (piense en una matriz dinámica).Puede probar la contención en O(n) time (a menos que la lista esté ordenada, entonces puede hacer una búsqueda binaria en O(log n) time).

Tal vez pueda explicar con un ejemplo en qué casos debería preferirse HashSet<T> frente a List<T>

Cuando desee probar la contención en O(1).

Para ser más precisos, demostremos con ejemplos

No puede utilizar HashSet como en el siguiente ejemplo.

HashSet<string> hashSet1 = new HashSet<string>(){"1","2","3"};
for (int i = 0; i < hashSet1.Count; i++)
    Console.WriteLine(hashSet1[i]);

hashSet1[i] produciría un error:

No se puede aplicar la indexación con [] a una expresión de tipo 'System.Collections.Generic.HashSet'

Puede utilizar la declaración foreach:

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

No puede agregar elementos duplicados a HashSet mientras List le permite hacer esto y mientras agrega un elemento a HashSet, puede verificar si contiene el elemento o no.

HashSet<string> hashSet1 = new HashSet<string>(){"1","2","3"};
if (hashSet1.Add("1"))
   Console.WriteLine("'1' is successfully added to hashSet1!");
else
   Console.WriteLine("'1' could not be added to hashSet1, because it contains '1'");

HashSet tiene algunas funciones útiles como IntersectWith, UnionWith, IsProperSubsetOf, ExceptWith, SymmetricExceptWith, etc.

IsProperSubsetOf:

HashSet<string> hashSet1 = new HashSet<string>() { "1", "2", "3", "4" };
HashSet<string> hashSet2 = new HashSet<string>() { "2", "4", "6", "8" };
HashSet<string> hashSet3 = new HashSet<string>() { "1", "2", "3", "4", "5" };
if (hashSet1.IsProperSubsetOf(hashSet3))
    Console.WriteLine("hashSet3 contains all elements of hashSet1.");
if (!hashSet1.IsProperSubsetOf(hashSet2))
    Console.WriteLine("hashSet2 does not contains all elements of hashSet1.");

UnionWith:

HashSet<string> hashSet1 = new HashSet<string>() { "3", "4" };
HashSet<string> hashSet2 = new HashSet<string>() { "2", "4", "6", "8" };
hashSet1.UnionWith(hashSet2); //hashSet1 -> 3, 2, 4, 6, 8

IntersectWith:

HashSet<string> hashSet1 = new HashSet<string>() { "3", "4", "8" };
HashSet<string> hashSet2 = new HashSet<string>() { "2", "4", "6", "8" }
hashSet1.IntersectWith(hashSet2);//hashSet1 -> 4, 8

ExceptWith:

 HashSet<string> hashSet1 = new HashSet<string>() { "1", "2", "3", "5", "6" };
 HashSet<string> hashSet2 = new HashSet<string>() { "1", "2", "3", "4" };
 hashSet1.ExceptWith(hashSet2);//hashSet1 -> 5, 6

SymmetricExceptWith:

 HashSet<string> hashSet1 = new HashSet<string>() { "1", "2", "3", "5", "6" };
 HashSet<string> hashSet2 = new HashSet<string>() { "1", "2", "3", "4" };
 hashSet1.SymmetricExceptWith(hashSet2);//hashSet1 -> 4, 5, 6

Por cierto, el orden no se conserva en HashSets. En el ejemplo, agregamos el elemento "2" al final, pero está en el segundo orden:

HashSet<string> hashSet1 = new HashSet<string>() { "3", "4", "8" };
hashSet1.Add("1");    // 3, 4, 8, 1
hashSet1.Remove("4"); // 3, 8, 1
hashSet1.Add("2");    // 3, 2 ,8, 1

Usar una List<T> cuando quieras:

  • Almacene una colección de artículos en un orden determinado.

Si conoce el índice del artículo que desea (en lugar del valor del artículo en sí), la recuperación es O(1).Si no conoce el índice, encontrar el artículo lleva más tiempo, O(n) para una colección sin clasificar.

Usar una Hashset<T> cuando quieras:

  • Descubra rápidamente si un determinado objeto está contenido en una colección.

Si conoce el nombre de lo que desea encontrar, la búsqueda es O(1) (esa es la parte 'Hash').No mantiene un orden como el List<T> lo hace y no puede almacenar duplicados (agregar un duplicado no tiene ningún efecto, esa es la parte 'Establecer').

Un ejemplo de cuándo utilizar un Hashset<T> sería si quieres saber si una palabra jugada en un juego de Scrabble es una palabra válida en inglés (u otro idioma).Aún mejor sería si quisieras crear un servicio web para ser utilizado por todas las instancias de una versión en línea de dicho juego.

A List<T> Sería una buena estructura de datos para crear el marcador para realizar un seguimiento de las puntuaciones de los jugadores.

La lista es una lista ordenada.Es

  • al que se accede mediante un índice de números enteros
  • puede contener duplicados
  • tiene un orden predecible

HashSet es un conjunto.Es:

  • Puede bloquear elementos duplicados (consulte Agregar (T) )
  • No garantiza el orden de los artículos dentro del conjunto
  • Tiene operaciones que esperaría en un conjunto, p. ej. , IntersectWith, IsProperSubsetOf, UnionWith.

La lista es más apropiada cuando desea acceder a su colección como si fuera como una matriz a la que podría agregar, insertar y eliminar elementos.HashSet es una mejor opción si desea tratar su colección como una "bolsa" de elementos en los que el orden no es importante o cuando desea compararlo con otros conjuntos utilizando operaciones como IntersectWith o UnionWith.

La lista no es necesariamente única, mientras que el hashset sí lo es.

Una lista es una colección ordenada de objetos de tipo T que, a diferencia de una matriz, puede agregar y eliminar entradas.

Usaría una lista en la que desea hacer referencia a los miembros en el orden en que los almacenó y accede a ellos por una posición en lugar del elemento en sí.

Un HashSet es como un diccionario en el que el elemento en sí mismo es la clave y el valor, el orden no está garantizado.

Usaría un HashSet donde quiera verificar que un objeto está en la colección

Si decide aplicar estas estructuras de datos al uso real en el desarrollo basado en datos, un HashSet es MUY útil para probar la replicación contra fuentes de adaptadores de datos, para la limpieza y migración de datos.

Además, si se usa la clase DataAnnotations, se puede implementar la lógica clave en las propiedades de la clase y controlar eficazmente un índice natural (agrupado o no) con un HashSet, donde esto sería muy difícil en una implementación de lista.

Una opción sólida para usar una lista es implementar genéricos para múltiples medios en un modelo de vista, como enviar una lista de clases a una vista MVC para un asistente DropDownList, y también para enviar como una construcción JSON a través de WebApi.La lista permite una lógica de colección de clases típica y mantiene la flexibilidad para un enfoque más parecido a una "interfaz" para calcular un modelo de vista única para diferentes medios.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top