Структура данных HashSet<T>
:
Структура данных библиотеки классов Framework HashSet<T>
была представлена в .NET Framework 3.5. Полный список его членов можно найти на справочной странице MSDN для HashSet<T>
.
HashSet<T>
более или менее моделируется после математического набора , что означает, что:
Может не содержать повторяющихся значений.
Его элементы не имеют определенного порядка; поэтому тип не реализует интерфейс IList<T>
, но более базовый ICollection<T>
. Как следствие, элементы внутри хеш-набора не могут быть доступны случайным образом через индексы; они могут повторяться только через перечислитель.
Доступны некоторые установленные функции, такие как Union
, Intersection
, IsSubsetOf
, IsSupersetOf
. Они могут пригодиться при работе с несколькими наборами.
Другое различие между HashSet<T>
и List<T>
состоит в том, что вызов метода Add(item)
хэш-набора возвращает логическое значение: true
, если элемент был добавлен, и false
в противном случае (поскольку он уже был найден установлен).
Почему бы не List<T>
?
Поскольку HashSet<T>
- это просто набор уникальных объектов, вы можете задаться вопросом, почему это должна быть структура данных. Обычный List<T>
может иметь такое же поведение, проверяя, найден ли объект в списке, прежде чем добавлять его.
Короткий ответ - скорость. Поиск по обычному List<T>
становится очень медленным и очень быстрым, так как добавляется больше элементов. Для HashSet<T>
требуется структура, которая обеспечит быструю скорость поиска и вставки.
Тесты:
Давайте сравним быстродействие HashSet<T>
с List<T>
.
Каждое испытание состояло из добавления целых чисел от 0 до 9999 к каждой коллекции. Однако мод 25 был применен к каждому целому числу. Мод 25 создает максимальное количество типов элементов 25. Поскольку было добавлено 10000 элементов, это вызвало 400 столкновений, что позволило структурам данных использовать свои алгоритмы поиска. Время измерялось 3 раза после 10000 испытаний и усреднялось.
Не обращайте слишком много внимания на конкретные времена выполнения тестов, поскольку они зависят от моего оборудования, но посмотрите, как они сравниваются друг с другом.
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>
выгодным.