В чем разница между HashSet и List ?
Можете ли вы объяснить, в чем разница между HashSet
и List
в .NET?
Может быть, вы можете объяснить примером, в каких случаях HashSet
должен быть предпочтительнее List
?
Благодарю.
- Разница между Iterator и Listiterator?
- Преобразовать список в список
- Получение элемента списка по индексу
- XML Сериализовать общий список сериализуемых объектов
- Java List.add () UnsupportedOperationException
- Различия между IQueryable, List, IEnumerator?
- Поиск по регистру без учета регистра
- Список привязок к DataGridView в WinForm
- Как я могу получить каждый n-й элемент из списка ?
- Лучшая практика для повторного создания списка или вызова clear ()
- Как клонировать общий список в C #?
- Подключить Список к ListBox и увидеть изменения источника данных в ListBox
- Преобразовать общий список / Перечислить в DataTable?
В отличие от List <> …
-
HashSet – это список без дублирующих членов.
-
Поскольку HashSet ограничивается только уникальными записями, внутренняя структура оптимизирована для поиска (по сравнению со списком) – она значительно быстрее
-
Добавление в HashSet возвращает логическое значение – false, если сбой не выполняется из-за уже существующего в Set.) Может выполнять операции математического набора с помощью Set: Union / Intersection / IsSubsetOf и т. Д.
-
HashSet не реализует IList только ICollection
-
Вы не можете использовать индексы с HashSet, только перечисляющие.
Основная причина использования HashSet заключается в том, если вы заинтересованы в выполнении операций Set.
Для двух наборов: hashSet1 и hashSet2
//returns a list of distinct items in both sets HashSet set3 = set1.Union( set2 );
летит по сравнению с эквивалентной операцией с использованием LINQ. Это также аккуратно писать!
HashSet
– это class, созданный для поиска O(1)
для сдерживания (т. Е. Содержит ли этот набор определенный объект и быстро отвечает на него).
List
– это class, предназначенный для предоставления вам коллекции с произвольным доступом O(1)
может динамически расти (подумайте о динамическом массиве). Вы можете проверить сдерживание в O(n)
времени (если список не отсортирован, тогда вы можете выполнить двоичный поиск в O(log n)
).
Может быть, вы можете объяснить примером, в каких случаях
HashSet
должен быть предпочтительнееList
Если вы хотите проверить сдерживание в O(1)
.
Чтобы быть более точным, продемонстрируйте примеры,
Вы не можете использовать HashSet, как в следующем примере.
HashSet hashSet1 = new HashSet (){"1","2","3"}; for (int i = 0; i < hashSet1.Count; i++) Console.WriteLine(hashSet1[i]);
hashSet1[i]
приведет к ошибке:
Невозможно применить индексирование с [] к выражению типа «System.Collections.Generic.HashSet»
Вы можете использовать оператор foreach:
foreach (var item in hashSet1) Console.WriteLine(item);
Вы не можете добавлять повторяющиеся элементы в HashSet, пока List позволяет вам это сделать, и пока вы добавляете элемент в HashSet, вы можете проверить, содержит ли он этот элемент или нет.
HashSet hashSet1 = new HashSet (){"1","2","3"}; if (hashSet1.Add("1")) Console.WriteLine("'1' is successfully added to hashSet1!"); else Console.WriteLine("'1' could not be added to hashSet1, because it contains '1'");
У HashSet есть некоторые полезные функции, такие как IntersectWith
, UnionWith
, IsProperSubsetOf
, ExceptWith
, SymmetricExceptWith
и т. Д.
IsProperSubsetOf
:
HashSet hashSet1 = new HashSet () { "1", "2", "3", "4" }; HashSet hashSet2 = new HashSet () { "2", "4", "6", "8" }; HashSet hashSet3 = new HashSet () { "1", "2", "3", "4", "5" }; if (hashSet1.IsProperSubsetOf(hashSet3)) Console.WriteLine("hashSet3 contains all elements of hashSet1."); if (!hashSet1.IsProperSubsetOf(hashSet2)) Console.WriteLine("hashSet2 does not contains all elements of hashSet1.");
UnionWith
:
HashSet hashSet1 = new HashSet () { "3", "4" }; HashSet hashSet2 = new HashSet () { "2", "4", "6", "8" }; hashSet1.UnionWith(hashSet2); //hashSet1 -> 3, 2, 4, 6, 8
IntersectWith
:
HashSet hashSet1 = new HashSet () { "3", "4", "8" }; HashSet hashSet2 = new HashSet () { "2", "4", "6", "8" } hashSet1.IntersectWith(hashSet2);//hashSet1 -> 4, 8
ExceptWith
:
HashSet hashSet1 = new HashSet () { "1", "2", "3", "5", "6" }; HashSet hashSet2 = new HashSet () { "1", "2", "3", "4" }; hashSet1.ExceptWith(hashSet2);//hashSet1 -> 5, 6
SymmetricExceptWith
:
HashSet hashSet1 = new HashSet () { "1", "2", "3", "5", "6" }; HashSet hashSet2 = new HashSet () { "1", "2", "3", "4" }; hashSet1.SymmetricExceptWith(hashSet2);//hashSet1 -> 4, 5, 6
Кстати, порядок не сохраняется в HashSets. В этом примере мы добавили элемент «2» последним, но он находится во втором порядке:
HashSet hashSet1 = new HashSet () { "3", "4", "8" }; hashSet1.Add("1"); // 3, 4, 8, 1 hashSet1.Remove("4"); // 3, 8, 1 hashSet1.Add("2"); // 3, 2 ,8, 1
Используйте List
если вы хотите:
- Храните коллекцию предметов в определенном порядке.
Если вам известен индекс нужного элемента (а не значение самого элемента), то поиск будет равен O(1)
. Если вы не знаете индекс, поиск элемента занимает больше времени, O(n)
для несортированной коллекции.
Используйте Hashset
если хотите:
- Быстро узнайте, содержится ли какой-либо объект в коллекции.
Если вы знаете имя вещи, которую хотите найти, Lookup is O(1)
(это часть «Хеш»). Он не поддерживает порядок, например List
, и вы не можете хранить дубликаты (добавление дубликата не имеет эффекта, это часть «Установить»).
Примером того, когда использовать Hashset
было бы, если вы хотите узнать, является ли слово, Hashset
в игре Scrabble, действительным словом на английском (или другом языке). Еще лучше было бы, если бы вы хотели создать веб-сервис, который будет использоваться всеми экземплярами онлайн-версии такой игры.
List
будет хорошей структурой данных для создания табло для отслеживания очков игроков.
Список – это упорядоченный список. это
- доступ к целым индексам
- может содержать дубликаты
- имеет предсказуемый порядок
HashSet – это набор. Это:
- Может блокировать повторяющиеся элементы (см. Add (T) )
- Не гарантирует порядок элементов в наборе
- Операции, которые вы ожидаете от набора, например , IntersectWith, IsProperSubsetOf, UnionWith.
Список более подходит, если вы хотите получить доступ к своей коллекции, как если бы это был массив, к которому вы могли добавлять, вставлять и удалять элементы. HashSet – лучший выбор, если вы хотите рассматривать свою коллекцию как «мешок» предметов, в которых порядок не важен, или когда вы хотите сравнить его с другими наборами, используя операции, такие как IntersectWith или UnionWith.
Список представляет собой упорядоченный набор объектов типа T, который в отличие от массива, который вы можете добавить и удалить записи.
Вы должны использовать список, в котором вы хотите ссылаться на членов в том порядке, в котором вы их сохранили, и вы получаете доступ к ним по позиции, а не по самому элементу.
HashSet похож на словарь, что сам элемент является ключом, а также значением, порядок не гарантируется.
Вы бы использовали HashSet, где вы хотите проверить, что объект находится в коллекции
Список не обязательно уникален, а hashset – для одного.
Если вы решите применить эти структуры данных к фактическому использованию в разработке, основанной на данных, HashSet ОЧЕНЬ полезен при тестировании репликации по источникам адаптеров данных, для очистки и миграции данных.
Кроме того, если использовать class DataAnnotations, можно реализовать логику Key в свойствах classа и эффективно управлять естественным индексом (с кластеризацией или нет) с помощью HashSet, где это будет очень сложно в реализации List.
Сильным вариантом для использования списка является реализация обобщений для нескольких сред в View Model, таких как отправка списка classов в MVC View для DropDownList Helper, а также для отправки в виде конструкции JSON через WebApi. Список позволяет использовать типичную логику сбора classов и обеспечивает гибкость для более «интерфейсного» подхода к вычислению единой модели представления для разных сред.