Nextrp [CPP] RU + Many GEOs Игра на карте России | NEXTRP

Почему словарь предпочтительнее Hashtable в C #?

c# .net vb.net data-structures

500569 просмотра

19 ответа

10480 Репутация автора

В большинстве языков программирования словари предпочтительнее хеш-таблиц. Каковы причины этого?

Автор: Nakul Chaudhary Источник Размещён: 19.11.2008 09:24

Ответы (19)


168 плюса

6879 Репутация автора

Потому Dictionaryчто это обобщенный класс ( Dictionary<TKey, TValue>), так что доступ к его содержимому безопасен для типов (т.е. вам не нужно Objectприводить из , как вы это делаете с Hashtable).

сравнить

var customers = new Dictionary<string, Customer>();
...
Customer customer = customers["Ali G"];

в

var customers = new Hashtable();
...
Customer customer = customers["Ali G"] as Customer;

Тем не менее, Dictionaryвнутренне реализовано как хеш-таблица, поэтому технически она работает так же.

Автор: gius Размещён: 19.11.2008 09:27

65 плюса

788135 Репутация автора

В .NET разница между Dictionary<,>и HashTableв первую очередь заключается в том, что первый тип является универсальным типом, так что вы получаете все преимущества универсальных типов с точки зрения статической проверки типов (и сокращенного бокса, но это не так велико, как люди думают в С точки зрения производительности - для бокса есть определенная стоимость памяти).

Автор: Marc Gravell Размещён: 19.11.2008 09:28

9 плюса

13641 Репутация автора

Это Hashtableслабо типизированная структура данных, поэтому вы можете добавлять ключи и значения любого типа в Hashtable. DictionaryКласс является типобезопасными Hashtableреализациями, а ключи и значение сильно типизированными. При создании Dictionaryэкземпляра вы должны указать типы данных как для ключа, так и для значения.

Автор: flesh Размещён: 19.11.2008 09:28

1476 плюса

47008 Репутация автора

Решение

Для чего это стоит, словарь , это (концептуально) хэш - таблицу.

Если вы имели в виду «почему мы используем Dictionary<TKey, TValue>класс вместо Hashtableкласса?», То это простой ответ: Dictionary<TKey, TValue>это универсальный тип, а Hashtableне. Это означает, что вы получаете безопасность типов Dictionary<TKey, TValue>, потому что вы не можете вставить в нее какой-либо случайный объект и вам не нужно приводить значения, которые вы берете.

Интересно, что Dictionary<TKey, TValue>реализация в .NET Framework основана на том Hashtable, что вы можете сказать из этого комментария в его исходном коде:

Общий словарь был скопирован из источника Hashtable

Источник

Автор: Michael Madsen Размещён: 19.11.2008 09:28

81 плюса

811 Репутация автора

К сведению: В .NET Hashtableявляется поточно-ориентированным для использования несколькими потоками читателей и одним потоком записи, тогда как в Dictionaryобщедоступных статических членах они являются поточно-ориентированными, но не гарантируется, что все члены экземпляра будут поточно-ориентированными

Из-за этого нам пришлось изменить все наши словари Hashtable.

Автор: user38902 Размещён: 19.11.2008 11:55

30 плюса

6950 Репутация автора

Люди говорят, что словарь - это то же самое, что хеш-таблица.

Это не обязательно правда. Хеш-таблица является одним из способов реализации словаря. Типичный для этого, и он может быть по умолчанию в .NET в Dictionaryклассе, но по определению он не единственный.

С таким же успехом вы могли бы реализовать словарь, используя связанный список или дерево поиска, это было бы не так эффективно (по некоторым показателям эффективности).

Автор: rix0rrr Размещён: 19.11.2008 01:03

5 плюса

0 Репутация автора

Еще одно отличие, которое я могу понять, это:

Мы не можем использовать словарь (generics) с веб-сервисами. Причина в том, что ни один стандарт веб-службы не поддерживает стандарт дженериков.

Автор: prashant Размещён: 17.04.2009 04:53

9 плюса

91 Репутация автора

Обратите внимание, что в MSDN написано: «Словарь <(Of <(TKey, TValue>)>) реализован как хеш-таблица », а не «Словарь <(Of <(TKey, TValue>)>) реализован как HashTable »

Словарь НЕ реализован как HashTable, но он реализован в соответствии с концепцией хеш-таблицы. Реализация не связана с классом HashTable из-за использования Generics, хотя внутри Microsoft могла бы использовать тот же код и заменить символы типа Object на TKey и TValue.

В .NET 1.0 Generics не существовало; именно здесь изначально начинались HashTable и ArrayList.

Автор: Brant Размещён: 24.01.2010 09:20

-3 плюса

0 Репутация автора

Согласно тому, что я вижу с помощью .NET Reflector :

[Serializable, ComVisible(true)]
public abstract class DictionaryBase : IDictionary, ICollection, IEnumerable
{
    // Fields
    private Hashtable hashtable;

    // Methods
    protected DictionaryBase();
    public void Clear();
.
.
.
}
Take note of these lines
// Fields
private Hashtable hashtable;

Таким образом, мы можем быть уверены, что DictionaryBase использует HashTable внутри.

Автор: Yuriy Zaletskyy Размещён: 09.03.2010 02:28

590 плюса

8856 Репутация автора

Dictionary<<< >>> Hashtableразличия:

  • Универсальный <<< >>> Неуниверсальный
  • Требуется собственная синхронизация потоков <<< >>> Предлагает потокобезопасную версию через Synchronized()метод
  • Пронумерованный предмет: KeyValuePair<<< >>> Пронумерованный предмет:DictionaryEntry
  • Более новые (> .NET 2.0 ) <<< >>> Старые (начиная с .NET 1.0 )
  • находится в System.Collections.Generic <<< >>> находится в System.Collections
  • Запрос на несуществующий ключ генерирует исключение <<< >>> Запрос на несуществующий ключ возвращает ноль
  • потенциально немного быстрее для типов значений <<< >>> немного медленнее (требуется упаковка / распаковка) для типов значений

Dictionary/ Hashtableсходства:

  • Оба являются внутренними хеш-таблицами == быстрый доступ к данным из многих элементов в соответствии с ключом
  • Оба требуют неизменных и уникальных ключей
  • Ключи обоих требуют собственного GetHashCode()метода

Аналогичные коллекции .NET (кандидаты на использование вместо Dictionary и Hashtable):

  • ConcurrentDictionary- потокобезопасен (может быть безопасно доступен из нескольких потоков одновременно)
  • HybridDictionary- оптимизированная производительность (для нескольких предметов, а также для многих предметов)
  • OrderedDictionary- значения могут быть доступны через индекс int (по порядку, в котором элементы были добавлены)
  • SortedDictionary- элементы автоматически сортируются
  • StringDictionary- строго типизирован и оптимизирован для строк
Автор: Thetam Размещён: 21.04.2011 10:32

5 плюса

8590 Репутация автора

Dictionary<> является универсальным типом, и поэтому он безопасен.

Вы можете вставить любой тип значения в HashTable, и это может иногда вызывать исключение. Но Dictionary<int>будет принимать только целочисленные значения и аналогично Dictionary<string>будет принимать только строки.

Итак, лучше использовать Dictionary<>вместо HashTable.

Автор: Kishore Kumar Размещён: 22.05.2012 08:07

21 плюса

2109 Репутация автора

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, чтобы объявить себя, мы можем указать тип ключа и значение, поэтому нет необходимости приводить при получении.

Давайте посмотрим на пример:

Хеш-таблица

class HashTableProgram
{
    static void Main(string[] args)
    {
        Hashtable ht = new Hashtable();
        ht.Add(1, "One");
        ht.Add(2, "Two");
        ht.Add(3, "Three");
        foreach (DictionaryEntry de in ht)
        {
            int Key = (int)de.Key; //Casting
            string value = de.Value.ToString(); //Casting
            Console.WriteLine(Key + " " + value);
        }

    }
}

Толковый словарь,

class DictionaryProgram
{
    static void Main(string[] args)
    {
        Dictionary<int, string> dt = new Dictionary<int, string>();
        dt.Add(1, "One");
        dt.Add(2, "Two");
        dt.Add(3, "Three");
        foreach (KeyValuePair<int, String> kv in dt)
        {
            Console.WriteLine(kv.Key + " " + kv.Value);
        }
    }
}
Автор: Sujit Размещён: 17.09.2012 11:10

14 плюса

32852 Репутация автора

Начиная с .NET Framework 3.5 есть еще и тот, HashSet<T>который предоставляет все плюсы, Dictionary<TKey, TValue>если вам нужны только ключи и никаких значений.

Поэтому, если вы используете a Dictionary<MyType, object>и всегда устанавливаете значение для nullимитации безопасной таблицы типов, вам, возможно, стоит подумать о переключении на HashSet<T>.

Автор: Oliver Размещён: 15.01.2013 10:29

7 плюса

426 Репутация автора

Объект Hashtable состоит из сегментов, которые содержат элементы коллекции. Ведро - это виртуальная подгруппа элементов в Hashtable, которая делает поиск и извлечение информации проще и быстрее, чем в большинстве коллекций .

Класс Dictionary имеет ту же функциональность, что и класс Hashtable. Словарь определенного типа (кроме Object) имеет лучшую производительность, чем Hashtable для типов значений, потому что элементы Hashtable имеют тип Object, и, следовательно, упаковка и распаковка обычно происходят при сохранении или получении типа значения.

Для дальнейшего чтения: Типы Hashtable и Коллекция словарей

Автор: mparkuk Размещён: 01.05.2014 09:37

15 плюса

1059 Репутация автора

Толковый словарь:

  • Он возвращает / выдает Exception, если мы пытаемся найти ключ, который не существует.

  • Это быстрее, чем Hashtable, потому что там нет упаковки и распаковки.

  • Только открытые статические члены являются потокобезопасными.

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

    Пример: Dictionary<string, string> <NameOfDictionaryVar> = new Dictionary<string, string>();

  • Dictionay - это безопасная от типов реализация Hashtable, Keysи она Valuesстрого типизирована.

Хеш-таблица:

  • Он возвращает ноль, если мы пытаемся найти ключ, который не существует.

  • Это медленнее, чем словарь, потому что он требует упаковки и распаковки.

  • Все члены Hashtable являются потокобезопасными,

  • Hashtable не является универсальным типом,

  • Hashtable - это слабо типизированная структура данных, мы можем добавлять ключи и значения любого типа.

Автор: Altaf Patel Размещён: 28.05.2014 07:53

14 плюса

1249 Репутация автора

В расширенном исследовании структур данных с использованием C # на MSDN говорится, что в стратегии разрешения конфликтов также есть различия :

Класс Hashtable использует технику, называемую перефразировкой .

Перефразировка работает следующим образом: существует набор хеш-функций, H 1 ... H n , и при вставке или извлечении элемента из хеш-таблицы первоначально используется хеш-функция H 1 . Если это приводит к столкновению, вместо этого пробуют H 2 и далее до H n, если необходимо.

Словарь использует технику, называемую цепочкой .

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

Автор: alexandrekow Размещён: 29.10.2014 11:12

5 плюса

1498 Репутация автора

Еще одно важное отличие состоит в том, что Hashtable является потокобезопасным. Hashtable имеет встроенную безопасность потоков для нескольких считывателей / писателей (MR / SW), что означает, что Hashtable позволяет ОДНОМ записывать вместе с несколькими считывателями без блокировки

В случае словаря нет никакой безопасности потока; если вам нужна безопасность потоков, вы должны реализовать собственную синхронизацию.

Чтобы уточнить дальше:

Hashtable обеспечивает некоторую безопасность потока через Synchronizedсвойство, которое возвращает потокобезопасную оболочку вокруг коллекции. Оболочка работает, блокируя всю коллекцию при каждой операции добавления или удаления. Поэтому каждый поток, который пытается получить доступ к коллекции, должен ждать своей очереди, чтобы взять одну блокировку. Это не масштабируется и может привести к значительному снижению производительности для больших коллекций. Также дизайн не полностью защищен от гонок.

Классы коллекций .NET Framework 2.0, такие как List<T>, Dictionary<TKey, TValue>и т. Д., Не обеспечивают никакой синхронизации потоков; пользовательский код должен обеспечивать всю синхронизацию, когда элементы добавляются или удаляются в нескольких потоках одновременно

Если вам нужна безопасность типов, а также безопасность потоков, используйте классы одновременных коллекций в .NET Framework. Дальнейшее чтение здесь .

Дополнительным отличием является то, что когда мы добавляем несколько записей в словарь, порядок, в котором они добавляются, сохраняется. Когда мы получим элементы из словаря, мы получим записи в том же порядке, в котором мы их вставили. Принимая во внимание, что Hashtable не сохраняет порядок вставки.

Автор: NullReference Размещён: 12.11.2015 10:17

8 плюса

424 Репутация автора

Хеш-таблица:

Ключ / значение будет преобразован в тип объекта (бокс) при сохранении в куче.

Ключ / значение необходимо преобразовать в нужный тип при чтении из кучи.

Эти операции очень дороги. Нам нужно как можно больше избегать коробок / распаковок.

Словарь: универсальный вариант HashTable.

Нет бокса / распаковки. Никаких преобразований не требуется.

Автор: Siva Sankar Gorantla Размещён: 13.07.2016 10:45

0 плюса

3325 Репутация автора

В большинстве языков программирования словари предпочтительнее хеш-таблиц

Я не думаю, что это обязательно так, большинство языков имеют один или другой, в зависимости от терминологии, которую они предпочитают .

Однако в C # очевидная причина (для меня) заключается в том, что C # HashTables и другие члены пространства имен System.Collections в значительной степени устарели. Они присутствовали в c # V1.1. Они были заменены из C # 2.0 классами Generic в пространстве имен System.Collections.Generic.

Автор: kristianp Размещён: 06.03.2019 01:58
32x32