110

Possible Duplicate:
Why Dictionary is preferred over hashtable in C#?

What is the difference between Dictionary and Hashtable. How to decide which one to use?

Community
  • 1
  • 1
blitzkriegz
  • 9,258
  • 18
  • 60
  • 71
  • 2
    It seems that this question should be closed as a duplicate, and its answers merged with one of the duplicates. – John Saunders May 18 '09 at 11:07
  • hopefully answers to this [question](http://stackoverflow.com/questions/301371/why-dictionary-is-preferred-over-hashtable-in-c) provides you a good answer – TheVillageIdiot May 18 '09 at 07:58
  • Although related to java language but [this](https://stackoverflow.com/q/40471/465053) thread is worth reading to know the difference between `HashMap` and `HashTable`. Few differences apply to C# world also. – RBT Aug 11 '17 at 03:10

7 Answers7

199

Simply, Dictionary<TKey,TValue> is a generic type, allowing:

  • static typing (and compile-time verification)
  • use without boxing

If you are .NET 2.0 or above, you should prefer Dictionary<TKey,TValue> (and the other generic collections)

A subtle but important difference is that Hashtable supports multiple reader threads with a single writer thread, while Dictionary offers no thread safety. If you need thread safety with a generic dictionary, you must implement your own synchronization or (in .NET 4.0) use ConcurrentDictionary<TKey, TValue>.

Gabe
  • 84,912
  • 12
  • 139
  • 238
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
86

Lets give an example that would explain the difference between hashtable and dictionary.

Here is a method that implements hashtable

public void MethodHashTable()
{
    Hashtable objHashTable = new Hashtable();
    objHashTable.Add(1, 100);    // int
    objHashTable.Add(2.99, 200); // float
    objHashTable.Add('A', 300);  // char
    objHashTable.Add("4", 400);  // string

    lblDisplay1.Text = objHashTable[1].ToString();
    lblDisplay2.Text = objHashTable[2.99].ToString();
    lblDisplay3.Text = objHashTable['A'].ToString();
    lblDisplay4.Text = objHashTable["4"].ToString();


    // ----------- Not Possible for HashTable ----------
    //foreach (KeyValuePair<string, int> pair in objHashTable)
    //{
    //    lblDisplay.Text = pair.Value + " " + lblDisplay.Text;
    //}
}

The following is for dictionary

  public void MethodDictionary()
  {
    Dictionary<string, int> dictionary = new Dictionary<string, int>();
    dictionary.Add("cat", 2);
    dictionary.Add("dog", 1);
    dictionary.Add("llama", 0);
    dictionary.Add("iguana", -1);

    //dictionary.Add(1, -2); // Compilation Error

    foreach (KeyValuePair<string, int> pair in dictionary)
    {
        lblDisplay.Text = pair.Value + " " + lblDisplay.Text;
    }
  }
Pritom Nandy
  • 1,245
  • 10
  • 6
  • 3
    As a note.....you can enumerate over Hashtable properties, as described here: http://msdn.microsoft.com/en-us/library/system.collections.hashtable.aspx. You have to use a DictionaryEntry as your variable, which can then provide key and value objects. –  May 30 '14 at 15:40
  • 1
    Superb answer,Also you can use DictionaryEntry for enumerate over Hashtable.Ex: foreach(DictionaryEntry dnty in objHashTable ){lblDisplay.Text= dnty.Value + " " +dnty.Key} – Manoj Weerasooriya Dec 18 '14 at 04:30
  • //Looping hastable foreach (DictionaryEntry entry in objHashTable ) { Console.WriteLine("{0}, {1}", entry.Key, entry.Value); } – Mike Oct 09 '18 at 03:03
24

There is one more important difference between a HashTable and Dictionary. If you use indexers to get a value out of a HashTable, the HashTable will successfully return null for a non-existent item, whereas the Dictionary will throw an error if you try accessing a item using a indexer which does not exist in the Dictionary

Rohit Gupta
  • 604
  • 2
  • 6
  • 15
13

Dictionary is typed (so valuetypes don't need boxing), a Hashtable isn't (so valuetypes need boxing). Hashtable has a nicer way of obtaining a value than dictionary IMHO, because it always knows the value is an object. Though if you're using .NET 3.5, it's easy to write an extension method for dictionary to get similar behavior.

If you need multiple values per key, check out my sourcecode of MultiValueDictionary here: multimap in .NET

Community
  • 1
  • 1
Frans Bouma
  • 8,259
  • 1
  • 27
  • 28
  • 2
    For multiple values per key: in .NET 3.5, you might also consider implementing `ILookup` (which is the multi-map interface). Unfortunately the default concrete implementation is immutable, but it is easy to re-implement (or add to your MultiValueDictionary). There is a simple example of such in MiscUtil (EditableLookup) – Marc Gravell May 18 '09 at 08:01
  • Good tip indeed, I had forgotten about that interface. I looked at the implementation in the BCL but it's indeed immutable so pretty much useless for every-day multi-value usage ;). I'll add the interface. – Frans Bouma May 18 '09 at 08:08
  • Done. Republished code: http://weblogs.asp.net/fbouma/archive/2009/05/18/multi-value-dictionary-c-source-code-net-3-5.aspx – Frans Bouma May 18 '09 at 09:06
  • Hmm, there's a problem with ILookup<>: it also implements an Enumerator, which is different from the Dictionary enumerator. When a Linq operator is used on the multivaluedictionary, it can't chose which enumerator to use as it also can use IEnumerable>, even though ILookup is implemented explicitly... Which makes it harder to use the dictionary as it requires explicit type specfication. – Frans Bouma May 18 '09 at 10:10
  • MultiDictionary is also present in PowerCollections: www.wintellect.com/powercollections.aspx – Dmitri Nesteruk Aug 17 '10 at 11:08
10

Want to add a difference:

Trying to acess a inexistent key gives runtime error in Dictionary but no problem in hashtable as it returns null instead of error.

e.g.

       //No strict type declaration
        Hashtable hash = new Hashtable();
        hash.Add(1, "One");
        hash.Add(2, "Two");
        hash.Add(3, "Three");
        hash.Add(4, "Four");
        hash.Add(5, "Five"); 
        hash.Add(6, "Six");
        hash.Add(7, "Seven");
        hash.Add(8, "Eight");
        hash.Add(9, "Nine");
        hash.Add("Ten", 10);// No error as no strict type

        for(int i=0;i<=hash.Count;i++)//=>No error for index 0
        {
            //Can be accessed through indexers
            Console.WriteLine(hash[i]);
        }
        Console.WriteLine(hash["Ten"]);//=> No error in Has Table

here no error for key 0 & also for key "ten"(note: t is small)

//Strict type declaration
        Dictionary<int,string> dictionary= new Dictionary<int, string>();
        dictionary.Add(1, "One");
        dictionary.Add(2, "Two");
        dictionary.Add(3, "Three");
        dictionary.Add(4, "Four");
        dictionary.Add(5, "Five");
        dictionary.Add(6, "Six");
        dictionary.Add(7, "Seven");
        dictionary.Add(8, "Eight");
        dictionary.Add(9, "Nine");
        //dictionary.Add("Ten", 10);// error as only key, value pair of type int, string can be added

        //for i=0, key doesn't  exist error
        for (int i = 1; i <= dictionary.Count; i++)
        {
            //Can be accessed through indexers
            Console.WriteLine(dictionary[i]);
        }
        //Error : The given key was not present in the dictionary.
        //Console.WriteLine(dictionary[10]);

here error for key 0 & also for key 10 as both are inexistent in dictionary, runtime error, while try to acess.

Pranav Singh
  • 17,079
  • 30
  • 77
  • 104
  • I suppose you should be using `LINQ` to find the `FirstOrDefault` item if you are trying to work with a collection outside foreach and for. – Piotr Kula Mar 12 '14 at 09:57
6

The Hashtable class is a specific type of dictionary class that uses an integer value (called a hash) to aid in the storage of its keys. The Hashtable class uses the hash to speed up the searching for a specific key in the collection. Every object in .NET derives from the Object class. This class supports the GetHash method, which returns an integer that uniquely identifies the object. The Hashtable class is a very efficient collection in general. The only issue with the Hashtable class is that it requires a bit of overhead, and for small collections (fewer than ten elements) the overhead can impede performance.

There is Some special difference between two which must be considered:

HashTable: is non-generic collection ,the biggest overhead of this collection is that it does boxing automatically for your values and in order to get your original value you need to perform unboxing , these to decrease your application performance as penalty.

Dictionary: This is generic type of collection where no implicit boxing, so no need to unboxing you will always get your original values which you were stored so it will improve your application performance.

the Second Considerable difference is:

if your were trying to access a value on from hash table on the basis of key that does not exist it will return null.But in the case of Dictionary it will give you KeyNotFoundException.

Rashmi Pandit
  • 23,230
  • 17
  • 71
  • 111
  • My comments are from MCTS 2.0 book and its gotten -ve rep ... how ironic!!!! :D – Rashmi Pandit May 18 '09 at 11:27
  • 2
    Not really very ironic... both Hashtable and Dictionary<,> are based on this approach, so it doesn't in any way answer the question of choosing between them. – Marc Gravell May 18 '09 at 11:46
  • 4
    The real irony is that I was reading the same MCTS book, got really confused as to which one to prefer, posted it here and got the same text i just read in the form of your answer!!! :) Thanks for replying nyways.. – blitzkriegz May 18 '09 at 12:26
3

ILookup Interface is used in .net 3.5 with linq.

The HashTable is the base class that is weakly type; the DictionaryBase abstract class is stronly typed and uses internally a HashTable.

I found a a strange thing about Dictionary, when we add the multiple entries in Dictionary, the order in which the entries are added is maintained. Thus if I apply a foreach on the Dictionary, I will get the records in the same order I have inserted them.

Whereas, this is not true with normal HashTable, as when I add same records in Hashtable the order is not maintained. As far as my knowledge goes, Dictionary is based on Hashtable, if this is true, why my Dictionary maintains the order but HashTable does not?

As to why they behave differently, it's because Generic Dictionary implements a hashtable, but is not based on System.Collections.Hashtable. The Generic Dictionary implementation is based on allocating key-value-pairs from a list. These are then indexed with the hashtable buckets for random access, but when it returns an enumerator, it just walks the list in sequential order - which will be the order of insertion as long as entries are not re-used.

shiv govind Birlasoft.:)