Why is Dictionary preferred over Hashtable in C#?

574,754

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

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).

Share:
574,754
Nakul Chaudhary
Author by

Nakul Chaudhary

Updated on October 25, 2021

Comments

  • Nakul Chaudhary
    Nakul Chaudhary over 2 years

    In most programming languages, dictionaries are preferred over hashtables. What are the reasons behind that?

    • Promit
      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
      arkon over 9 years
      @Promit I always thought the Dictionary was an implementation of the Hashtable.
    • Radinator
      Radinator almost 8 years
      I 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
      kristianp over 5 years
      The original title of the question was c# specific. I have restored "in c#" to the title.
    • jrh
      jrh about 5 years
      Not to be confused with HashSet<T> which unlike HashTable, is generic.
  • MordechayS
    MordechayS over 15 years
    And also generic collections are a lot faster as there's no boxing/unboxing
  • MordechayS
    MordechayS over 15 years
    Not sure about a Hashtable with the above statement, but for ArrayList vs List<t> it's true
  • Guvante
    Guvante about 15 years
    Hashtable uses Object to hold things internally (Only non-generic way to do it) so it would also have to box/unbox.
  • Triynko
    Triynko about 14 years
    Fun. 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
    Triynko about 14 years
    Alternatively, 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
    snemarch almost 14 years
    System.Collections.Generic.Dictionary<TKey,TValue> doesn't derive from DictionaryBase.
  • snemarch
    snemarch almost 14 years
    MS 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
    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
    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 the Hashtable in multithreaded code: msdn.microsoft.com/en-us/library/dd287191.aspx
  • Robert Hensing
    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
    Brian J about 11 years
    If 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
    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
    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
    Michael Madsen about 11 years
    @BrianJ: Both HashTable (class) and Dictionary (class) are hash tables (concept), but a HashTable is not a Dictionary, nor is a Dictionary a HashTable. They are used in very similar fashions, and Dictionary<Object,Object> can act in the same untyped manner that a HashTable does, but they do not directly share any code (though parts are likely to be implemented in a very similar fashion).
  • Trident D'Gao
    Trident D'Gao almost 11 years
    @Guillaume86, this is why you use TryGetValue instead msdn.microsoft.com/en-us/library/bb347013.aspx
  • Jim Balter
    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
    supercat over 10 years
    I 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
    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
    Mayur Dhingra over 10 years
    Only public static members are thread safe in a Dictionary whereas all the members are thread safe in a Hashtable.
  • Cheng Chen
    Cheng Chen about 10 years
    +1 for StringDictionary...btw StringDictionary isn't the same as Dictionary<string, string> when you use the default constructor.
  • Joseph Hamilton
    Joseph Hamilton over 9 years
    I was talking about in .NET, since that's what he referenced in his response.
  • VoteCoffee
    VoteCoffee over 9 years
    The ParallelExtensionsExtras @code.msdn.microsoft.com/windowsdesktop/… contains an ObservableConcurrentDictionary which is great fir binding as well as concurrency.
  • ToolmakerSteve
    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
    Siddharth over 8 years
    We 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
    mkb over 8 years
    awesome explanation, it's really nice you also listed the similarities to lessen the questions that might comes to one's mind
  • Ron
    Ron almost 8 years
    instead 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
    amit jha over 6 years
  • sansy
    sansy about 6 years
    Dictionary supports more linq statements than Hashtable
  • Jim Balter
    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
    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
    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
    Joseph Hamilton over 5 years
    @JimBalter .Net HashTable -> docs.microsoft.com/en-us/dotnet/api/…
  • Joseph Hamilton
    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
    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
    Bill Norman over 5 years
    One 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
    kristianp over 5 years
    In 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
    kristianp over 5 years
    Whoops, not HasKey, it should be ContainsKey.
  • supercat
    supercat over 4 years
    From 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 of Dictionary 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
    Steve Dunn over 3 years
    StringDictionary is now considered obsolete in favour of Dictionary<string,string> *with a suitable StringComparer instance