В большинстве языков программирования словари предпочтительнее хеш-таблиц. Каковы причины этого?
c#
.net
vb.net
data-structures
Накул Чаудхари
источник
источник
Dictionary
это реализацияHashtable
.HashTable
. Когда они добавили дженерики в язык, они назвали дженериковую версиюDictionary
. Оба хеш-таблицы.Ответы:
Для чего это стоит, словарь , является (концептуально) хэш - таблицу.
Если вы имели в виду «почему мы используем
Dictionary<TKey, TValue>
класс вместоHashtable
класса?», То это простой ответ:Dictionary<TKey, TValue>
это универсальный тип, аHashtable
не. Это означает, что вы получаете безопасность типовDictionary<TKey, TValue>
, потому что вы не можете вставить в нее какой-либо случайный объект и вам не нужно приводить значения, которые вы вынимаете.Интересно, что
Dictionary<TKey, TValue>
реализация в .NET Framework основана на томHashtable
, что вы можете сказать из этого комментария в его исходном коде:Источник
источник
HashTable
(класс), иDictionary
(класс) являются хеш-таблицами (концепция), но aHashTable
не является aDictionary
, а также не являетсяDictionary
aHashTable
. Они используются очень похожими способами иDictionary<Object,Object>
могут действовать таким же нетипизированным способом, что и aHashTable
, но они напрямую не разделяют какой-либо код (хотя части, вероятно, будут реализованы очень похожим образом).Dictionary
<<< >>>Hashtable
различия:Synchronized()
методKeyValuePair
<<< >>> Пронумерованный предмет:DictionaryEntry
Dictionary
/Hashtable
сходства:GetHashCode()
методаАналогичные коллекции .NET (кандидаты на использование вместо словаря и Hashtable):
ConcurrentDictionary
- потокобезопасен (может быть безопасно доступен из нескольких потоков одновременно)HybridDictionary
- оптимизированная производительность (для нескольких предметов, а также для многих предметов)OrderedDictionary
- значения могут быть доступны через индекс int (по порядку, в котором элементы были добавлены)SortedDictionary
- элементы автоматически сортируютсяStringDictionary
- строго типизирован и оптимизирован для строкисточник
StringDictionary
... кстати,StringDictionary
это не то же самое, чтоDictionary<string, string>
при использовании конструктора по умолчанию.Потому
Dictionary
что это обобщенный класс (Dictionary<TKey, TValue>
), так что доступ к его содержимому безопасен для типов (то есть вам не нужноObject
приводить из , как вы это делаете сHashtable
).сравнить
в
Тем не менее,
Dictionary
он реализован как хеш-таблица внутри, поэтому технически он работает так же.источник
К вашему сведению: в .NET,
Hashtable
потокобезопасен для использования несколькими потоками читателей и одним потоком записи, в то время как вDictionary
общедоступных статических членах они являются поточно-ориентированными, но не гарантируется, что все члены экземпляра будут поточно-ориентированнымиИз-за этого нам пришлось изменить все наши словари
Hashtable
.источник
ConcurrentDictionary
класс, в котором все открытые / защищенные методы реализованы как поточно-ориентированные. Если вам не нужно поддерживать устаревшие платформы, это позволит вам заменитьHashtable
многопоточный код: msdn.microsoft.com/en-us/library/dd287191.aspxВ .NET разница между
Dictionary<,>
иHashTable
в первую очередь заключается в том, что первый тип является универсальным типом, так что вы получаете все преимущества универсальных типов с точки зрения статической проверки типов (и сокращения объема упаковки, но это не так велико, как люди думают в Условия исполнения - для бокса есть определенная стоимость памяти).источник
Люди говорят, что словарь такой же, как хеш-таблица.
Это не обязательно правда. Хеш-таблица является одним из способов реализации словаря. Типичный в этом, и это может быть по умолчанию в .NET в
Dictionary
классе, но по определению он не единственный.С таким же успехом вы могли бы реализовать словарь, используя связанный список или дерево поиска, это было бы не так эффективно (по некоторым показателям эффективности).
источник
Dictionary<K,V>
.IDictionary<K,V>
может быть все что угодно :)Collections
&Generics
полезны для обработки группы объектов. В .NET все объекты коллекций подчиняются интерфейсуIEnumerable
, который в свою очередь имеетArrayList(Index-Value))
&HashTable(Key-Value)
. После .NET Framework 2.0,ArrayList
&HashTable
были заменены наList
&Dictionary
. ТеперьArraylist
&HashTable
больше не используются в современных проектах.Разница между
HashTable
&Dictionary
,Dictionary
является общей, гдеHastable
не является общей . Мы можем добавить любой тип объектаHashTable
, но при получении нам нужно привести его к требуемому типу. Таким образом, это не безопасно типа. Но для тогоdictionary
, чтобы объявить себя, мы можем указать тип ключа и значение, поэтому нет необходимости приводить при получении.Давайте посмотрим на пример:
Хеш-таблица
Толковый словарь,
источник
Толковый словарь:
Возвращает / выдает Exception, если мы пытаемся найти ключ, который не существует.
Это быстрее, чем Hashtable, потому что там нет упаковки и распаковки.
Только открытые статические члены являются потокобезопасными.
Словарь - это универсальный тип, который означает, что мы можем использовать его с любым типом данных (при создании необходимо указывать типы данных как для ключей, так и для значений).
Пример:
Dictionary<string, string> <NameOfDictionaryVar> = new Dictionary<string, string>();
Dictionay - это безопасная от типов реализация Hashtable,
Keys
и онаValues
строго типизирована.Хеш-таблица:
Он возвращает ноль, если мы пытаемся найти ключ, который не существует.
Это медленнее, чем словарь, потому что он требует упаковки и распаковки.
Все члены в Hashtable являются потокобезопасными,
Hashtable не является универсальным типом,
Hashtable - это слабо типизированная структура данных, мы можем добавлять ключи и значения любого типа.
источник
Dictionary.TryGetValue
В расширенном исследовании структур данных с использованием C # на MSDN говорится, что есть также разница в стратегии разрешения коллизий :
Класс Hashtable использует технику, называемую перефразировкой .
Словарь использует технику, называемую цепочкой .
источник
Начиная с .NET Framework 3.5 есть еще один,
HashSet<T>
который предоставляет все плюсы,Dictionary<TKey, TValue>
если вам нужны только ключи и никаких значений.Поэтому, если вы используете a
Dictionary<MyType, object>
и всегда устанавливаете значение дляnull
имитации типовой безопасной хеш-таблицы, вам следует подумать о переключении наHashSet<T>
.источник
Это
Hashtable
слабо типизированная структура данных, поэтому вы можете добавлять ключи и значения любого типа вHashtable
.Dictionary
Класс является типобезопаснымиHashtable
реализациями, а ключи и значение сильно типизированными. При созданииDictionary
экземпляра необходимо указать типы данных как для ключа, так и для значения.источник
Обратите внимание, что MSDN говорит: «Словарь <(Of <(TKey, TValue>)>) реализован как хеш-таблица », а не «Словарь <(Of <(TKey, TValue>)>) класс реализован как HashTable »
Словарь НЕ реализован как HashTable, но он реализован в соответствии с концепцией хеш-таблицы. Реализация не связана с классом HashTable из-за использования Generics, хотя внутри Microsoft могла бы использовать тот же код и заменить символы типа Object на TKey и TValue.
В .NET 1.0 Generics не существовало; именно здесь изначально начинались HashTable и ArrayList.
источник
Хеш-таблица:
Ключ / значение будет преобразован в тип объекта (бокс) при сохранении в куче.
Ключ / значение необходимо преобразовать в нужный тип при чтении из кучи.
Эти операции очень дороги. Нам нужно как можно больше избегать коробок / распаковок.
Толковый словарь : универсальный вариант HashTable.
Нет бокса / распаковки. Никаких преобразований не требуется.
источник
Объект Hashtable состоит из сегментов, которые содержат элементы коллекции. Ведро - это виртуальная подгруппа элементов в Hashtable, которая делает поиск и извлечение данных проще и быстрее, чем в большинстве коллекций .
Класс Dictionary имеет ту же функциональность, что и класс Hashtable. Словарь определенного типа (кроме Object) имеет лучшую производительность, чем Hashtable для типов значений, потому что элементы Hashtable имеют тип Object, и, следовательно, упаковка и распаковка обычно происходят при сохранении или получении типа значения.
Для дальнейшего чтения: Типы Hashtable и Коллекция словарей
источник
Еще одно важное отличие состоит в том, что Hashtable является потокобезопасным. Hashtable имеет встроенную безопасность потоков для нескольких считывателей / писателей (MR / SW), что означает, что Hashtable позволяет ОДНОМ записывающему устройству вместе с несколькими считывателями без блокировки.
В случае словаря нет безопасности потока; если вам нужна безопасность потоков, вы должны реализовать собственную синхронизацию.
Чтобы уточнить дальше:
Если вам нужна безопасность типов, а также безопасность потоков, используйте классы одновременных коллекций в .NET Framework. Дальнейшее чтение здесь .
Дополнительным отличием является то, что когда мы добавляем несколько записей в словарь, порядок, в котором они добавляются, сохраняется. Когда мы получаем элементы из словаря, мы получим записи в том же порядке, в котором мы их вставили. Принимая во внимание, что Hashtable не сохраняет порядок вставки.
источник
Hashset
гарантии безопасности потоков MR / SW в сценариях использования, которые не включают удаления . Я думаю, что он должен был быть полностью безопасным для MR / SW, но безопасная обработка удалений значительно увеличивает затраты на безопасность MR / SW. Несмотря на то, что вDictionary
сценариях без удаления проектирование могло бы обеспечить безопасность MR / SW с минимальными затратами, я думаю, что MS хотела бы не рассматривать сценарии без удаления как «особые».Еще одно отличие, которое я могу понять:
Мы не можем использовать словарь <KT, VT> (generics) с веб-сервисами. Причина в том, что ни один стандарт веб-службы не поддерживает стандарт дженериков.
источник
Dictionary<>
является универсальным типом, и поэтому он безопасен.Вы можете вставить любой тип значения в HashTable, и это может иногда вызывать исключение. Но
Dictionary<int>
будет принимать только целочисленные значения и аналогичноDictionary<string>
будет принимать только строки.Итак, лучше использовать
Dictionary<>
вместоHashTable
.источник
Я не думаю, что это обязательно так, у большинства языков есть один или другой, в зависимости от терминологии, которую они предпочитают .
Однако в C # очевидной причиной (для меня) является то, что C # HashTables и другие члены пространства имен System.Collections в значительной степени устарели. Они присутствовали в c # V1.1. Они были заменены из C # 2.0 классами Generic в пространстве имен System.Collections.Generic.
источник
Согласно тому, что я вижу с помощью .NET Reflector :
Таким образом, мы можем быть уверены, что DictionaryBase использует HashTable внутри.
источник