Why is Dictionary preferred over Hashtable in C#?
Solution 1
For what it's worth, a Dictionary is (conceptually) a hash table.
If you meant "why do we use the Dictionary<TKey, TValue>
class instead of the Hashtable
class?", then it's an easy answer: Dictionary<TKey, TValue>
is a generic type, Hashtable
is not. That means you get type safety with Dictionary<TKey, TValue>
, because you can't insert any random object into it, and you don't have to cast the values you take out.
Interestingly, the Dictionary<TKey, TValue>
implementation in the .NET Framework is based on the Hashtable
, as you can tell from this comment in its source code:
The generic Dictionary was copied from Hashtable's source
Solution 2
Differences
Dictionary |
Hashtable |
---|---|
Generic | Non-Generic |
Needs own thread synchronization | Offers thread safe version through Synchronized() method |
Enumerated item: KeyValuePair
|
Enumerated item: DictionaryEntry
|
Newer (> .NET 2.0) | Older (since .NET 1.0) |
is in System.Collections.Generic | is in System.Collections |
Request to non-existing key throws exception | Request to non-existing key returns null |
potentially a bit faster for value types | bit slower (needs boxing/unboxing) for value types |
Similarities:
- Both are internally hashtables == fast access to many-item data according to key
- Both need immutable and unique keys
- Keys of both need own
GetHashCode()
method
Alternative .NET collections:
(candidates to use instead of Dictionary and Hashtable)
-
ConcurrentDictionary
- thread safe (can be safely accessed from several threads concurrently) -
HybridDictionary
- optimized performance (for few items and also for many items) -
OrderedDictionary
- values can be accessed via int index (by order in which items were added) -
SortedDictionary
- items automatically sorted -
StringDictionary
- strongly typed and optimized for strings (now Deprecated in favor of Dictionary<string,string>)
Solution 3
Because Dictionary
is a generic class ( Dictionary<TKey, TValue>
), so that accessing its content is type-safe (i.e. you do not need to cast from Object
, as you do with a Hashtable
).
Compare
var customers = new Dictionary<string, Customer>();
...
Customer customer = customers["Ali G"];
to
var customers = new Hashtable();
...
Customer customer = customers["Ali G"] as Customer;
However, Dictionary
is implemented as hash table internally, so technically it works the same way.
Solution 4
FYI: In .NET, Hashtable
is thread safe for use by multiple reader threads and a single writing thread, while in Dictionary
public static members are thread safe, but any instance members are not guaranteed to be thread safe.
We had to change all our Dictionaries back to Hashtable
because of this.
Solution 5
In .NET, the difference between Dictionary<,>
and HashTable
is primarily that the former is a generic type, so you get all the benefits of generics in terms of static type checking (and reduced boxing, but this isn't as big as people tend to think in terms of performance - there is a definite memory cost to boxing, though).
Nakul Chaudhary
Updated on October 25, 2021Comments
-
Nakul Chaudhary over 2 years
In most programming languages, dictionaries are preferred over hashtables. What are the reasons behind that?
-
Promit about 15 years> This is not necessarily true. A hash table is an implementation of a dictionary. A typical one at that, and it may be the default one in .NET, but it's not by definition the only one. I'm not sure that this is required by the ECMA standard, but the MSDN documentation very clearly calls it out as being implemented as a hashtable. They even provide the SortedList class for times when an alternative is more reasonable.
-
arkon over 9 years@Promit I always thought the
Dictionary
was an implementation of theHashtable
. -
Radinator almost 8 yearsI think the reason is, that in a dictionary you can define the type of the key and the value for your selfe. the Hashtable can only take objects and saves the pairs based on the hash (from object.GetHashCode() ).
-
kristianp over 5 yearsThe original title of the question was c# specific. I have restored "in c#" to the title.
-
jrh about 5 yearsNot to be confused with HashSet<T> which unlike
HashTable
, is generic.
-
-
MordechayS over 15 yearsAnd also generic collections are a lot faster as there's no boxing/unboxing
-
MordechayS over 15 yearsNot sure about a Hashtable with the above statement, but for ArrayList vs List<t> it's true
-
Guvante about 15 yearsHashtable uses Object to hold things internally (Only non-generic way to do it) so it would also have to box/unbox.
-
Triynko about 14 yearsFun. The Dictionary<T> source code looks a lot cleaner and faster. It might be better to use Dictionary and implement your own synchronization. If the Dictionary reads absolutely need to be current, then you'd simply have to synchronize access to the read/write methods of the Dictionary. It would be a lot of locking, but it would be correct.
-
Triynko about 14 yearsAlternatively, if your reads don't have to be absolutely current, you could treat the dictionary as immutable. You could then grab a reference to the Dictionary and gain performance by not synchronizing reads at all (since it's immutable and inherently thread-safe). To update it, you construct a complete updated copy of the Dictionary in the background, then just swap the reference with Interlocked.CompareExchange (assuming a single writing thread; multiple writing threads would require synchronizing the updates).
-
snemarch almost 14 yearsSystem.Collections.Generic.Dictionary<TKey,TValue> doesn't derive from DictionaryBase.
-
snemarch almost 14 yearsMS docs say: "Retrieving a value by using its key is very fast, close to O(1), because the Dictionary <(Of <(TKey, TValue >)>) class is implemented as a hash table." - so you should be guaranteed a hashtable when dealing with
Dictionary<K,V>
.IDictionary<K,V>
could be anything, though :) -
Joseph Hamilton almost 13 years@rix0rrr - I think you've got that backwards, a Dictionary uses a HashTable not a HashTable uses a Dictionary.
-
Dan Is Fiddling By Firelight over 12 years.Net 4.0 added the
ConcurrentDictionary
class which has all public/protected methods implemented to be thread-safe. If you don't need to support legacy platforms this would let you replace theHashtable
in multithreaded code: msdn.microsoft.com/en-us/library/dd287191.aspx -
Robert Hensing over 11 years@JosephHamilton - rix0rrr got it right: "A hash table is an implementation of a dictionary." He means the concept "dictionary", not the class (note the lower case). Conceptually, a hash table implements a dictionary interface. In .NET, Dictionary uses a hash table to implement IDictionary. It's messy ;)
-
Brian J about 11 yearsIf Dictionary is generic, wouldn't it be more accurate to say a hash table is a dictionary? The whole "squares are rectangles, but not all rectangles are squares" thing?
-
Michael Madsen about 11 years@BrianJ: A "hash table" (two words) is the computer science term for this kind of structure; Dictionary is a specific implementation. A HashTable corresponds roughly to a Dictionary<object,object> (though with slightly different interfaces), but both are implementations of the hash table concept. And of course, just to confuse matters further, some languages call their hash tables "dictionaries" (e.g. Python) - but the proper CS term is still hash table.
-
Brian J about 11 years@MichaelMadsen So to make sure I understand you correctly, a
HashTable
data structure is a Dictionary, which is a hash table (concept), right? -
Michael Madsen about 11 years@BrianJ: Both
HashTable
(class) andDictionary
(class) are hash tables (concept), but aHashTable
is not aDictionary
, nor is aDictionary
aHashTable
. They are used in very similar fashions, andDictionary<Object,Object>
can act in the same untyped manner that aHashTable
does, but they do not directly share any code (though parts are likely to be implemented in a very similar fashion). -
Trident D'Gao almost 11 years@Guillaume86, this is why you use TryGetValue instead msdn.microsoft.com/en-us/library/bb347013.aspx
-
Jim Balter almost 11 years@BrianJ "If Dictionary is generic, wouldn't it be more accurate to say a hash table is a dictionary?" -- No, because "generic" has a specific meaning in programming languages that has little to do with the English language term. A "generic" class or method is a class or method that has one or more type parameters.
-
supercat over 10 yearsI recall reading that HashTable is only reader-writer thread-safe in the scenario where information is never deleted from the table. If a reader is asking for an item which is in the table while a different item is being deleted, and the reader would to look in more than one place for the item, it's possible that while the reader is searching the writer might move the item from a place which hasn't been examined to one which has, thus resulting in a false report that the item does not exist.
-
Matthijs Wessels over 10 years@MichealMadsen, I think the confusion comes from the fact that outside of C# the term Dictionary is also used as an abstract data type for which the
Hash Table
is a solution with specific running times. Also, generic also has a meaning outside of C#, so if you don't know C#, "generic dictionary" could be interpreted as the abstract data structure. -
Mayur Dhingra over 10 yearsOnly public static members are thread safe in a Dictionary whereas all the members are thread safe in a Hashtable.
-
Cheng Chen about 10 years+1 for
StringDictionary
...btwStringDictionary
isn't the same asDictionary<string, string>
when you use the default constructor. -
Joseph Hamilton over 9 yearsI was talking about in .NET, since that's what he referenced in his response.
-
VoteCoffee over 9 yearsThe ParallelExtensionsExtras @code.msdn.microsoft.com/windowsdesktop/… contains an ObservableConcurrentDictionary which is great fir binding as well as concurrency.
-
ToolmakerSteve over 9 years@JosephHamilton: implements (or implementation of) does not even remotely mean the same thing as uses. Quite the opposite. Perhaps it would have been clearer if he said it slightly differently (but with the same meaning): "a hash table is one way to implement a dictionary". That is, if you want the functionality of a dictionary, one way to do that (to implement the dictionary), is to use a hashtable.
-
Siddharth over 8 yearsWe can use generic lists (List<string>) in soap based web service. But, we cannot use dictionary (or hashtable) in a webservice. I think the reason for this is that the .net xmlserializer cannot handle dictionary object.
-
mkb over 8 yearsawesome explanation, it's really nice you also listed the similarities to lessen the questions that might comes to one's mind
-
Ron almost 8 yearsinstead of explicitly assigning the datatype for KeyValuePair, we could use var. So, this would reduce typing - foreach (var kv in dt)...just a suggestion.
-
amit jha over 6 years
-
sansy about 6 yearsDictionary supports more linq statements than Hashtable
-
Jim Balter over 5 years"So we can be sure that DictionaryBase uses a HashTable internally." -- That's nice, but it has nothing to do with the question.
-
Jim Balter over 5 years"It returns/throws Exception if we try to find a key which does not exist." Not if you use
Dictionary.TryGetValue
-
Jim Balter over 5 years@JosephHamilton "I was talking about in .NET, since that's what he referenced in his response." -- you're wrong in any case; the .NET Dictionary class does not use or in any other way reference the .NET Hashtable class (and there is no .NET HashTable class). The answer by rix0rrr is completely right and not backwards in any way.
-
Joseph Hamilton over 5 years@JimBalter .Net HashTable -> docs.microsoft.com/en-us/dotnet/api/…
-
Joseph Hamilton over 5 years@JimBalter "The Dictionary<TKey,TValue> generic class provides a mapping from a set of keys to a set of values. Each addition to the dictionary consists of a value and its associated key. Retrieving a value by using its key is very fast, close to O(1), because the Dictionary<TKey,TValue> class is implemented as a hash table." docs.microsoft.com/en-us/dotnet/api/…
-
Jim Balter over 5 years@JosephHamilton And how is any of that relevant? First, "Hashtable" != "HashTable". Second, "a hash table" != "the .NET Hashtable class". All of this was discussed repeatedly here ... please read more carefully. I won't respond further to your inaccuracies.
-
Bill Norman over 5 yearsOne of the advantages of a hashtable over a dictionary is that if a key does not exist in a dictionary, it will throw an error. If a key does not exist in a hashtable, it just returns null.
-
kristianp over 5 yearsIn C# I would still avoid using System.Collections.Hashtable as they don't have the advantage of generics. You can use Dictionary's TryGetValue or HasKey if you don't know if the key will exist.
-
kristianp over 5 yearsWhoops, not HasKey, it should be ContainsKey.
-
supercat over 4 yearsFrom what I understand, the
Hashset
guarantees MR/SW thread safety in usage scenarios that do not involve deletions. I think it may have been intended to be fully MR/SW safe, but handling deletions safely greatly increases the expense of MR/SW safety. While the design ofDictionary
could have offered MR/SW safety at minimal cost in no-delete scenarios, I think MS wanted to avoid treating no-delete scenarios as "special". -
Steve Dunn over 3 years
StringDictionary
is now considered obsolete in favour ofDictionary<string,string>
*with a suitableStringComparer
instance