Определите: что такое HashSet?


420

HashSet Структура данных C # HashSet была представлена ​​в .NET Framework 3.5. Полный список реализованных участников можно найти на странице HashSet MSDN .

  1. Где это используется?
  2. Почему вы хотите использовать это?



Он использует хеш-таблицу внутри. если у вас есть хорошая реализация хеш-таблицы (например, Dictionary <T>), вы можете легко реализовать HashSet самостоятельно.
Раз Мегрелидзе

Ответы:


614
    1. A HashSetсодержит набор объектов, но позволяет легко и быстро определить, находится ли объект в наборе или нет. Это достигается за счет внутреннего управления массивом и сохранения объекта с использованием индекса, который вычисляется из хеш-кода объекта. Посмотрите здесь

    2. HashSetнеупорядоченная коллекция, содержащая уникальные элементы Он имеет стандартные операции сбора Add, Remove, Contains, но поскольку он использует реализацию на основе хеша, эти операции являются O (1). (В отличие от List, например, O (n) для Contains и Remove.) HashSetТакже предоставляет стандартные операции над множествами, такие как объединение , пересечение и симметричная разность . Посмотрите здесь

  1. Существуют разные реализации множеств. Некоторые делают операции вставки и поиска очень быстрыми за счет хэширования элементов. Однако это означает, что порядок добавления элементов теряется. Другие реализации сохраняют добавленный порядок за счет более медленного времени выполнения.

HashSetКласс в C # идет на первый подход, таким образом , не сохраняя порядок элементов. Это намного быстрее, чем обычный List. Некоторые базовые тесты показали, что HashSet работает быстрее при работе с основными типами (int, double, bool и т. Д.). Это намного быстрее при работе с объектами класса. Итак, суть в том, что HashSet работает быстро.

Единственный улов в HashSetтом, что нет доступа по индексам. Чтобы получить доступ к элементам, вы можете использовать перечислитель или встроенную функцию, чтобы преобразовать HashSetв Listи выполнить итерацию. Посмотрите здесь


13
Две вещи, hashset и подобные - это .NET, а не C #. Также HashSet не сохраняет порядок. Попробуйте добавить и удалить элементы из хеш-набора, вы узнаете, будете ли вы выполнять итерации позже ..
nawfal

13

A HashSetимеет внутреннюю структуру (хэш), где элементы можно быстро найти и идентифицировать. Недостатком является то, что итерация HashSet(или получение элемента по индексу) довольно медленная.

Так почему кто-то хочет знать, существует ли запись в наборе?

Одна из ситуаций, когда a HashSetполезна, - это получение различных значений из списка, в котором могут существовать дубликаты. Как только элемент добавлен в элемент, HashSetон быстро определяет, существует ли элемент ( Containsоператор).

Другие преимущества HashSetявляются операции Set: IntersectWith, IsSubsetOf, IsSupersetOf, Overlaps, SymmetricExceptWith, UnionWith.

Если вы знакомы с языком ограничения объектов, то вы определите эти операции над множествами. Вы также увидите, что это на один шаг ближе к реализации исполняемого UML.


20
Re: недостаток. Нет, итерация по HashSet проходит очень быстро. Во-вторых, невозможно получить элемент по индексу. Фактически, элементы хранятся неупорядоченными.
Найджел Touch

@Nigel Touch. Итерации выполняются быстро, если вы не заботитесь об индексе (порядок, в котором они были добавлены). Однако, если вас беспокоит индекс, индекс должен храниться с каждым хеш-ключом, и, следовательно, он может быть довольно медленным, потому что в списке нужно искать исчерпывающе, чтобы найти правильный элемент. Это поведение сильно отличается от списка, в котором элементы индексируются в порядке их добавления.
K Rey

Имеет смысл, почему это будет быстро, потому что нет двух одинаковых хешей. Включение запроса для использования подхода «короткого замыкания», быстро исключающего определенные критерии.
Chef_Code

8

Проще говоря, не раскрывая кухонных секретов: набор в целом - это коллекция, которая не содержит повторяющихся элементов и элементы которой не имеют определенного порядка. Таким образом, A HashSet<T>похож на универсальный List<T>, но оптимизирован для быстрого поиска (через хеш-таблицы, как следует из названия) за счет потери порядка.


1
Но может ли HashSet <T> хранить два объекта с одинаковыми данными, например два класса Product, каждый из которых имеет одинаковые свойства с одинаковым содержимым?
Йохан Херстад

Я думаю, мы никогда не узнаем
Денни

@JohanHerstad Предполагая, что EqualityComparer для вашего класса заботится об этих свойствах, или вы создаете HashSet с IEqualityComparer, который заботится об этих свойствах, я не понимаю, почему это не так. Документация HashSet становится ясно , что он опирается на один или другой , чтобы определить уникальность.
Бекон Биты

2

С точки зрения приложения, если вам нужно только избежать дубликатов, то HashSetэто то, что вы ищете, поскольку сложности поиска, вставки и удаления имеют O (1) -константу . Это означает, что не имеет значения, сколько элементов HashSetимеет, потребуется столько же времени, чтобы проверить, есть ли такой элемент или нет, плюс, поскольку вы вставляете элементы в O (1), это делает его идеальным для такого рода вещей.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.