В чем разница между HashSet и List ?
-
29-10-2019 - |
Вопрос
Не могли бы вы объяснить, в чем разница между HashSet<T>
и List<T>
в .NET?
Может быть, вы можете объяснить на примере, в каких случаях HashSet<T>
следует предпочесть List<T>
?
Решение
В отличие от списка <> ...
-
HashSet - это список без повторяющихся элементов.
-
Поскольку HashSet должен содержать только уникальные записи, внутренняя структура оптимизирована для поиска (по сравнению со списком) - это значительно быстрее
-
Добавление в HashSet возвращает логическое значение - false, если добавление не удается из-за того, что уже существует в Set
-
Может выполнять математические операции над множеством над Set: Union / Intersection / IsSubsetOf и т. д.
-
HashSet не реализует только ICollection IList
-
Вы не можете использовать индексы с HashSet, только перечислители.
Основная причина использования HashSet - если вы заинтересованы в выполнении операций Set.
Дано 2 набора: hashSet1 и hashSet2
родовое словолетает по сравнению с аналогичной операцией с использованием LINQ.Тоже аккуратнее писать!
Другие советы
HashSet<T>
- это класс, разработанный для того, чтобы дать вам возможность поиска кода O(1)
для включения (т.е. содержит ли эта коллекция конкретный объект и быстро сообщить мне ответ).
List<T>
- это класс, предназначенный для предоставления вам коллекции с произвольным доступом O(1)
, которая может расти динамически (подумайте о динамическом массиве).Вы можете протестировать включение во время сгенерированного кодового кода (если список не отсортирован, тогда вы можете выполнить бинарный поиск по сгенерированному времени кодового кода).
Возможно, вы можете объяснить на примере, в каких случаях O(n)
следует предпочесть O(log n)
.
Если вы хотите протестировать содержание в кодовом коде.
Чтобы быть более точным, давайте продемонстрируем на примерах,
Вы не можете использовать HashSet, как в следующем примере.
родовое слово hashSet1[i]
приведет к ошибке:
Невозможно применить индексирование с помощью [] к выражению типа 'System.Collections.Generic.HashSet'
Вы можете использовать инструкцию foreach:
родовое словоВы не можете добавлять повторяющиеся элементы в HashSet, пока List позволяет это делать и пока вы добавляете элемент в HashSet, вы можете проверить, содержит он элемент или нет.
родовое слово HashSet имеет несколько полезных функций, таких как IntersectWith
, UnionWith
, IsProperSubsetOf
, ExceptWith
, SymmetricExceptWith
и т. д.
IsProperSubsetOf
:
UnionWith
:
IntersectWith
:
ExceptWith
:
SymmetricExceptWith
:
Кстати, порядок в HashSets не сохраняется. В этом примере мы добавили элемент «2» последним, но во втором порядке:
родовое словоИспользуйте общий код кода, если хотите:
- Храните коллекцию предметов в определенном порядке.
Если вам известен индекс элемента, который вы хотите (а не значение самого элемента), извлекается код List<T>
. Если вы не знаете индекс, поиск элемента займет больше времени, сгенерируйте код для несортированной коллекции.
Используйте общий кодовый тег, если хотите:
- Быстро узнать, содержится ли в коллекции определенный объект.
Если вы знаете название объекта, который хотите найти, Lookup - это O(1)
(это часть "Хеш"). Он не поддерживает порядок, как это делает O(n)
, и вы не можете хранить дубликаты (добавление дубликата не имеет никакого эффекта, это часть «Установить»).
Примером того, когда использовать генерирующий кодовый код, может быть ситуация, когда вы хотите узнать, является ли слово, используемое в игре Scrabble, допустимым словом на английском (или другом языке). Еще лучше было бы, если бы вы хотели создать веб-сервис, который будет использоваться всеми экземплярами онлайн-версии такой игры.
Генеракодический код тега может быть хорошей структурой данных для создания табло для отслеживания результатов игроков.
Список - это упорядоченный список.Это
- доступ по целочисленному индексу
- может содержать дубликаты
- имеет предсказуемый порядок.
HashSet - это набор.Это:
- Может блокировать повторяющиеся элементы (см. Добавить (T) )
- Не гарантирует порядок элементов в наборе.
- Имеет ожидаемые операции с набором, например , IntersectWith, IsProperSubsetOf, UnionWith.
Список более уместен, когда вы хотите получить доступ к своей коллекции, как если бы это было похоже на массив, к которому вы можете добавлять, вставлять и удалять элементы.HashSet - лучший выбор, если вы хотите рассматривать свою коллекцию как «мешок» элементов, порядок которых не важен, или если вы хотите сравнить ее с другими наборами, используя такие операции, как IntersectWith или UnionWith.
Список не обязательно уникален, например, хеш-набор.
Список - это упорядоченная коллекция объектов типа T, которые, в отличие от массива, могут добавлять и удалять записи.
Вы могли бы использовать список, в котором вы хотите ссылаться на элементы в том порядке, в котором вы их сохранили, и вы обращаетесь к ним по позиции, а не по самому элементу.
HashSet похож на словарь, в котором сам элемент является ключом, а также значением, порядок не гарантируется.
Вы можете использовать HashSet, где хотите проверить, находится ли объект в коллекции
Если вы решите применить эти структуры данных к фактическому использованию в разработке, управляемой данными, HashSet ОЧЕНЬ полезен при тестировании репликации с источниками адаптеров данных для очистки и миграции данных.
Кроме того, при использовании класса DataAnnotations можно реализовать логику ключа для свойств класса и эффективно управлять естественным индексом (кластеризованным или нет) с помощью HashSet, где это было бы очень сложно в реализации списка.
Хорошим вариантом использования списка является реализация универсальных шаблонов для нескольких сред в модели представления, таких как отправка списка классов в представление MVC для вспомогательной функции DropDownList, а также для отправки в виде конструкции JSON через WebApi.Список допускает типичную логику сбора классов и сохраняет гибкость для более «интерфейсного» подхода к вычислению одной модели представления для различных сред.