Кто-нибудь знает, есть ли хороший эквивалент коллекции Java Set
на C#? Я знаю, что вы можете несколько имитировать набор, используя Dictionary
или HashTable
, заполняя, но игнорируя значения, но это не очень элегантный способ.C# Set collection?
ответ
Попробуйте HashSet:
HashSet (Of T) класс обеспечивает набор операций с высокой производительностью. Набор представляет собой набор, который не содержит повторяющихся элементов и элементы которого не имеют особого порядка ...
Емкость объекта HashSet (Of T) - это количество элементов, которые может удерживать объект. Емкость объекта HashSet (Of T) автоматически увеличивается по мере добавления элементов к объекту.
Класс HashSet (Of T) основан на модели математических наборов и обеспечивает высокопроизводительные операции с множеством операций, аналогичные доступу к клавишам коллекций Dictionary(Of TKey, TValue) или Hashtable. Говоря простыми словами, класс HashSet (Of T) можно рассматривать как коллекцию Dictionary(Of TKey, TValue) без значений.
HashSet (Of T) сбор не отсортирован и не может содержать повторяющиеся элементы ...
К сожалению, HashSets не были добавлены только недавно. Если вы работаете в более ранней версии фреймворка, вам придется придерживаться своего словаря «munged Dictionary» <> или Hashtable. – 2008-10-08 16:36:48
Если вы используете .NET 3.5, вы можете использовать HashSet<T>
. Это правда, что .NET не обслуживает наборы, а также Java.
Может также помочь Wintellect PowerCollections.
Кто-нибудь знает, почему это называется HashSet, а не только Set? – Wouter 2009-06-24 07:57:22
Я подозреваю, что Set - это ключевое слово на некоторых языках, что может вызвать проблемы. – 2009-06-24 08:10:40
`Set` - ключевое слово в VB. – 2009-11-26 01:02:07
Я использую Iesi.Collections http://www.codeproject.com/KB/recipes/sets.aspx
Он используется в многих проектов OSS, я первым наткнулся на нее в NHibernate
Посмотрите PowerCollections над в CodePlex. Помимо Set и OrderedSet, он имеет несколько других полезных типов коллекций, таких как Deque, MultiDictionary, Bag, OrderedBag, OrderedDictionary и OrderedMultiDictionary.
Для получения дополнительных коллекций есть также C5 Generic Collection Library.
Вы можете реализовать свою собственную выполнимую реализацию набора за пару часов. Я использовал это, когда мне пришлось это делать (извините, у меня нет кода): http://java.sun.com/j2se/1.4.2/docs/api/java/util/Set.html
Я использую обертку вокруг Dictionary<T, object>
, сохраняя значения в значениях. Это дает O (1) добавлять, искать и удалять по клавишам, и все намерения и цели действуют как набор.
Я знаю, что это старый поток, но я столкнулся с той же проблемой и нашел HashSet очень ненадежным, потому что, учитывая одно и то же семя, GetHashCode() возвратил разные коды. Итак, я подумал, почему бы не просто использовать список и скрыть способ добавить как этот
public class UniqueList<T> : List<T>
{
public new void Add(T obj)
{
if(!Contains(obj))
{
base.Add(obj);
}
}
}
Поскольку список использует метод Equals исключительно для определения равенства, вы можете определить метод Equals от типа T, чтобы убедиться, что вы получить желаемые результаты.
Структура HashSet<T>
данные:
структура HashSet<T>
данных библиотеки классов в Framework был введен в .NET Framework 3.5. Полный список его членов можно найти на странице MSDN reference page for HashSet<T>
.
HashSet<T>
более или менее по образцу mathematical set, что означает, что:
Это может не содержать повторяющиеся значения.
Его элементы не имеют особого порядка; поэтому тип не реализует интерфейс
IList<T>
, но тем более базовыйICollection<T>
. Как следствие, элементы внутри хэш-набора не могут быть случайно доступны через индексы; они могут быть перепрограммированы только через счетчик.Некоторые функции множества таких как
Union
,Intersection
,IsSubsetOf
,IsSupersetOf
доступны. Они могут пригодиться при работе с несколькими наборами.
Еще одно различие между HashSet<T>
и List<T>
является вызовом Add(item)
метод хэш-установочных наборов возвращает логическое значение: true
, если элемент был добавлен, и false
в противном случае (поскольку он уже был найден в наборе).
Почему не List<T>
?
Поскольку HashSet<T>
- это просто коллекция уникальных объектов, вы можете задаться вопросом, почему это должна быть структура данных. Обычный List<T>
может иметь такое же поведение, проверяя, найден ли объект в списке перед его добавлением.
Короткий ответ - скорость. Поиск по нормальному List<T>
происходит очень медленно, так как добавляется больше элементов. A HashSet<T>
требует конструкцию структуры, которая будет обеспечивать быструю скорость поиска и вставки.
Ориентиры:
Давайте сравним скорость работы с HashSet<T>
против в List<T>
.
Каждое испытание состояло из добавления целых чисел от 0 до 9999 в каждую коллекцию. Однако mod 25 применялся к каждому целому числу. Мод 25 делает максимальные типы элементов 25. Поскольку было добавлено 10 000 элементов, это вызвало 400 столкновений, что дало структурам данных возможность использовать их алгоритмы поиска. Время измерялось 3 раза после 10 000 испытаний и усреднялось.
Не уделяйте слишком много внимания конкретному времени работы тестов, поскольку они зависят от моего оборудования, но посмотрите, как они сравниваются друг с другом.
Average time [ms]
----------------------------
HashSet<T> 2,290
List<T> 5,505
Теперь давайте сделаем элементы объектов вместо примитивных типов. Я написал быстрый класс Person
с тремя полями: Name
, LastName
и ID
.Поскольку я не использовал какой-либо конкретный способ сравнения объектов, все элементы будут добавлены без коллизий. На этот раз в каждую коллекцию было добавлено 1000 Person
объектов. Общее время 3 комплектов 1000 испытаний было усреднено.
Average time [ms]
----------------------------
HashSet<Person> 201
List<Person> 3,000
Как вы можете видеть, разница в запущенное время становится астрономическим при использовании объектов, что делает HashSet<T>
выгодными.
Если вы используете .NET 4.0 или более поздней версии:
В случае, когда вам нужно сортировать затем использовать SortedSet<T>
. В противном случае, если вы этого не сделаете, используйте HashSet<T>
, так как это O(1)
для поиска и управления операциями. В то время как SortedSet<T>
- O(log n)
для поиска и манипулирования операциями.
Здесь вы можете найти основную информацию о Hashset. http://dotnetk.com/c-hashset-csharp/ – 2017-10-08 11:53:50