Hashtable
This C# class
optimizes lookups. It computes a hash of each key you add, and then uses this hash code to look up the element very quickly.
This is an older .NET Framework type. It is slower than the generic Dictionary
type. But if an old program uses Hashtable
, it is helpful to know how to use this type.
ContainsKey
To start, we create a Hashtable
. You will want to call ContainsKey
on your Hashtable
with the key contents. This method returns true if the key is found.
Contains
works the same way. We see an example of using the indexer with the square brackets.Hashtable
returns plain objects so you must cast them.using System; using System.Collections; // Create a Hashtable. Hashtable hashtable = new Hashtable(); hashtable.Add("bird", 1); hashtable.Add("cat", 2); hashtable.Add("dog", 10); // See if the Hashtable contains this key. bool result = hashtable.ContainsKey("bird"); Console.WriteLine(result); // Test the Contains method. result = hashtable.Contains("bird"); Console.WriteLine(result); // Get value of cat key. int value = (int)hashtable["bird"]; Console.WriteLine(value);True True 1
The example adds 3 integer keys, with one string
value each, to the Hashtable
. You can loop through the Hashtables by using DictionaryEntry
in a foreach
-loop.
foreach
we use a DictionaryEntry
. A DictionaryEntry
contains 2 objects: the key and the value.using System;
using System.Collections;
Hashtable hashtable = new Hashtable();
hashtable[1] = "One";
hashtable[2] = "Two";
hashtable[13] = "Thirteen";
foreach (DictionaryEntry entry in hashtable)
{
Console.WriteLine("{0}, {1}", entry.Key, entry.Value);
}13, Thirteen
2, Two
1, One
The example here adds string
keys and int
keys. Each of the key-value pairs has different types. You can put them all in the same Hashtable
.
InvalidCastException
. We avoid this with "is" or "as."using System; using System.Collections; class Program { static Hashtable GetHashtable() { Hashtable hashtable = new Hashtable(); hashtable.Add(300, "Carrot"); hashtable.Add("Area", 1000); return hashtable; } static void Main() { Hashtable hashtable = GetHashtable(); string value1 = (string)hashtable[300]; Console.WriteLine(value1); int value2 = (int)hashtable["Area"]; Console.WriteLine(value2); } }Carrot 1000
You can use the as
-operator to attempt to cast an object to a specific reference type. If the cast does not succeed, the result will be null
.
is
-operator. This operator returns true or false based on the result.Hashtable
, you can reduce the number of casts by using the as
-operator. This is a performance warning given by FxCop
.using System; using System.Collections; using System.IO; Hashtable hashtable = new Hashtable(); hashtable.Add(400, "Blazer"); // This cast will succeed. string value = hashtable[400] as string; if (value != null) { Console.WriteLine(value); } // This cast won't succeed, but won't throw. StreamReader reader = hashtable[400] as StreamReader; if (reader != null) { Console.WriteLine("Unexpected"); } // You can get the object and test it. object value2 = hashtable[400]; if (value2 is string) { Console.Write("is string: "); Console.WriteLine(value2); }Blazer is string: Blazer
Keys
, valuesWe can loop over keys and values, or store them in an ArrayList
. This example shows all the keys, then all the values, and then stores the keys in an ArrayList
.
Hashtable
example uses the Keys
property. This property returns all the keys.Keys
instance property on the Hashtable
instance.Hashtable
instance.ArrayList
with the copy constructor and pass it the Keys
(or Values) property as the argument.using System; using System.Collections; Hashtable hashtable = new Hashtable(); hashtable.Add(400, "Blaze"); hashtable.Add(500, "Fiery"); hashtable.Add(600, "Fire"); hashtable.Add(800, "Immolate"); // Display the keys. foreach (int key in hashtable.Keys) { Console.WriteLine(key); } // Display the values. foreach (string value in hashtable.Values) { Console.WriteLine(value); } // Put keys in an ArrayList. ArrayList arrayList = new ArrayList(hashtable.Keys); foreach (int key in arrayList) { Console.WriteLine(key); }800 (First loop) 600 500 400 Immolate (Second loop) Fire Fiery Blaze 800 (Third loop) 600 500 400
Count
, ClearYou can count the elements in a Hashtable
with the Count
property. The example also shows using the Clear method to erase all the Hashtable
contents.
Clear()
is to reassign your Hashtable
reference to a new Hashtable()
.Count
is a constant-time accessor. It returns an integer and is a simple accessor with low resource demands.using System; using System.Collections; // Add four elements to Hashtable. Hashtable hashtable = new Hashtable(); hashtable.Add(1, "x"); hashtable.Add(2, "y"); hashtable.Add(3, "z"); hashtable.Add(10, "q"); // Get Count of Hashtable. int count = hashtable.Count; Console.WriteLine(count); // Clear the Hashtable. hashtable.Clear(); // Get Count of Hashtable again. Console.WriteLine(hashtable.Count);4 0
We test the Hashtable
collection against the Dictionary
. The benchmark first populates an equivalent version of each collection.
Hashtable
from System.Collections
and calls ContainsKey
in a loop.ContainsKey
from the generic Dictionary
collection. It searches for the same keys.Hashtable
is slower than the Dictionary
code. Replacing code that uses Hashtable
with Dictionary
will likely make it faster.using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; const int _max = 1000000; // Set up collections. Hashtable hashtable = new Hashtable(); for (int i = 0; i <= 30000; i++) { hashtable[i.ToString("00000")] = i; } var dictionary = new Dictionary<string, int>(); for (int i = 0; i <= 30000; i++) { dictionary.Add(i.ToString("00000"), i); } // Version 1: use Hashtable. var s1 = Stopwatch.StartNew(); for (int i = 0; i < _max; i++) { if (!hashtable.ContainsKey("09999") || !hashtable.ContainsKey("30000")) { return; } } s1.Stop(); // Version 2: use Dictionary. var s2 = Stopwatch.StartNew(); for (int i = 0; i < _max; i++) { if (!dictionary.ContainsKey("09999") || !dictionary.ContainsKey("30000")) { return; } } s2.Stop(); Console.WriteLine(((double)(s1.Elapsed.TotalMilliseconds * 1000000) / _max).ToString("0.00 ns")); Console.WriteLine(((double)(s2.Elapsed.TotalMilliseconds * 1000000) / _max).ToString("0.00 ns"));66.99 ns Hashtable 51.22 ns Dictionary
Keys
and values, notesThe Keys
and Values public accessors return a collection of the keys and values in the Hashtable
at the time they are accessed.
Hashtable
instance itself.Hashtable
is an older collection that is obsoleted by the Dictionary
collection. Knowing how to use it is critical when maintaining older programs. These programs are important.