Поделиться через


Типы коллекций Hashtable и Dictionary

Класс System.Collections.Hashtable и универсальные классы System.Collections.Generic.Dictionary<TKey,TValue> и System.Collections.Concurrent.ConcurrentDictionary<TKey,TValue> реализуют интерфейс System.Collections.IDictionary. Универсальный класс Dictionary<TKey,TValue> также реализует универсальный интерфейс IDictionary<TKey,TValue>. Таким образом, каждый элемент в этих коллекциях является парой "ключ-значение".

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

Универсальный класс HashSet<T> — это неупорядоченная коллекция для хранения уникальных элементов.

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

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

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

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

Классы Dictionary<TKey,TValue> и ConcurrentDictionary<TKey,TValue> имеют ту же функциональность, что и класс Hashtable. Объект Dictionary<TKey,TValue> конкретного типа (отличного от Object) обеспечивает лучшую производительность, чем Hashtable для типов значений. Это происходит потому, что элементы Hashtable относятся к типу Object, поэтому при сохранении или извлечении типа значения происходит упаковка или распаковка. Класс ConcurrentDictionary<TKey,TValue> следует использовать в случае, когда к коллекции могут обращаться несколько потоков одновременно.

См. также