namespace generic example collection colecciones c# .net collections set

generic - C#Set colección?



namespace collection c# (10)

Como han mencionado otros, no parece haber una implementación de conjunto en el estándar .NET con semántica de conjunto.

Vea esta pregunta para HashSet por qué HashSet no siempre se desea como una implementación de conjunto.

Si está interesado en rodar su propia clase de conjunto, aquí hay un enfoque simple:

public sealed class MathSet<T> : HashSet<T>, IEquatable<MathSet<T>> { public override int GetHashCode() => this.Select(elt => elt.GetHashCode()).Sum().GetHashCode(); public bool Equals(MathSet<T> obj) => SetEquals(obj); public override bool Equals(object obj) => Equals(obj as MathSet<T>); public static bool operator ==(MathSet<T> a, MathSet<T> b) => ReferenceEquals(a, null) ? ReferenceEquals(b, null) : a.Equals(b); public static bool operator !=(MathSet<T> a, MathSet<T> b) => !(a == b); }

Ejemplo de uso:

var a = new MathSet<int> { 1, 2, 3 }; var b = new MathSet<int> { 3, 2, 1 }; var c = a.Equals(b); // true var d = new MathSet<MathSet<int>> { a, b }; // contains one element var e = a == b; // true

¿Alguien sabe si hay un buen equivalente a la colección Set de Java en C #? Sé que puedes imitar un conjunto utilizando un Dictionary o una HashTable pero ignorando los valores, pero esa no es una forma muy elegante.


Echa un vistazo a PowerCollections en CodePlex. Además de Set y OrderedSet, tiene algunos otros tipos de colección útiles, como Deque, MultiDictionary, Bag, OrderedBag, OrderedDictionary y OrderedMultiDictionary.

Para más colecciones, también está la Biblioteca de colecciones genéricas C5 .


Intente HashSet :

La clase HashSet (Of T) proporciona operaciones de conjunto de alto rendimiento. Un conjunto es una colección que no contiene elementos duplicados, y cuyos elementos no están en ningún orden en particular ...

La capacidad de un objeto HashSet (Of T) es el número de elementos que el objeto puede contener. La capacidad de un objeto HashSet (Of T) aumenta automáticamente a medida que se agregan elementos al objeto.

La clase HashSet (Of T) se basa en el modelo de conjuntos matemáticos y proporciona operaciones de conjuntos de alto rendimiento similares al acceso a las claves de las Dictionary(Of TKey, TValue) o Hashtable . En términos simples, la clase HashSet (Of T) se puede considerar como una colección de Dictionary(Of TKey, TValue) sin valores.

Una colección HashSet (Of T) no está ordenada y no puede contener elementos duplicados ...



Sé que este es un subproceso antiguo, pero me estaba topando con el mismo problema y encontré que HashSet no era confiable porque dado el mismo valor inicial, GetHashCode () devolvió códigos diferentes. Entonces, pensé, ¿por qué no usar una Lista y ocultar el método de agregar como este?

public class UniqueList<T> : List<T> { public new void Add(T obj) { if(!Contains(obj)) { base.Add(obj); } } }

Debido a que List utiliza el método Equals únicamente para determinar la igualdad, puede definir el método Equals en su tipo T para asegurarse de obtener los resultados deseados.



Utilizo una envoltura alrededor de un Dictionary<T, object> , almacenando nulos en los valores. Esto le da a O (1) agregar, buscar y eliminar las claves, y para todos los propósitos y propósitos actúa como un conjunto.



La estructura de datos HashSet<T> :

La estructura de datos HashSet<T> Framework Class Library se introdujo en .NET Framework 3.5. Puede encontrar una lista completa de sus miembros en la HashSet .

HashSet<T> está más o menos modelado después de un conjunto matemático , lo que significa que:

  1. Puede que no contenga valores duplicados.

  2. Sus elementos no están en ningún orden particular; por lo tanto, el tipo no implementa la interfaz IList<T> , sino la más básica ICollection<T> . Como consecuencia, no se puede acceder aleatoriamente a los elementos dentro de un conjunto de hash a través de índices; solo se pueden iterar a través de un enumerador.

  3. Ciertas funciones de conjunto como Union , Intersection , IsSubsetOf , IsSupersetOf están disponibles. Estos pueden ser útiles cuando se trabaja con varios conjuntos.

Otra diferencia entre HashSet<T> y List<T> es que llamar al método Add(item) un conjunto hash devuelve un valor booleano: true si se agregó el elemento, y false contrario (porque ya se encontró en el conjunto).

¿Por qué no List<T> ?

Dado que un HashSet<T> es simplemente una colección de objetos únicos, podría preguntarse por qué tiene que ser una estructura de datos. Una List<T> normal List<T> podría tener el mismo comportamiento al verificar si un objeto se encuentra en la lista antes de agregarlo.

La respuesta corta es la velocidad. La búsqueda en una List<T> normal List<T> vuelve muy lenta muy rápido a medida que se agregan más elementos. Un HashSet<T> requiere un diseño de estructura que permita búsquedas rápidas y velocidades de inserción.

Puntos de referencia:

Comparemos la velocidad de rendimiento de un HashSet<T> frente a una List<T> .

Cada prueba consistió en agregar enteros de 0 a 9,999 a cada colección. Sin embargo, el mod 25 se aplicó a cada entero. El Mod 25 hace los tipos máximos de elementos 25. Desde que se agregaron 10,000 elementos, esto obligó a que ocurrieran 400 colisiones, dando a las estructuras de datos la oportunidad de usar sus algoritmos de búsqueda. Los tiempos se midieron 3 veces después de 10,000 intentos y se promediaron.

No preste demasiada atención a los tiempos de ejecución específicos de las pruebas, ya que dependen de mi hardware, pero observe cómo se comparan entre sí.

Average time [ms] ---------------------------- HashSet<T> 2,290 List<T> 5,505

Ahora vamos a hacer objetos de elementos en lugar de tipos primitivos. Escribí una clase de Person rápida con tres campos: Name , LastName e ID . Como no incluí ninguna forma específica de comparar objetos, todos los elementos se agregarán sin colisiones. Esta vez se agregaron 1,000 objetos Person a cada colección para una única prueba. Los tiempos totales de 3 series de 1,000 intentos se promediaron.

Average time [ms] ---------------------------- HashSet<Person> 201 List<Person> 3,000

Como puede ver, la diferencia en los tiempos de ejecución se vuelve astronómica cuando se usan objetos, lo que hace que HashSet<T> ventajoso.


Si está utilizando .NET 4.0 o posterior:

En el caso de que necesite una ordenación, use SortedSet<T> . De lo contrario, si no lo hace, use HashSet ya que es O(1) para las operaciones de búsqueda y manipulación. Mientras que SortedSet<T> es O(log n) para las operaciones de búsqueda y manipulación.