C-Sharp | Java | Python | Swift | GO | WPF | Ruby | Scala | F# | JavaScript | SQL | PHP | Angular | HTML
First: The example adds 3 integer keys, with one string value each, to the Hashtable object.
Foreach: You can loop through the Hashtables by using the DictionaryEntry type in a foreach-loop.
ForeachDictionaryEntry: In foreach we use a DictionaryEntry. A DictionaryEntry contains 2 objects: the key and the value.
DictionaryEntryWriteLine: The WriteLine call contains a format string that displays the key-value pairs with a comma.
C# program that adds entries to Hashtable
using System;
using System.Collections;
class Program
{
static void Main()
{
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);
}
}
}
Output
13, Thirteen
2, Two
1, One
Also: Contains works the same way. We see an example of using the indexer with the square brackets.
Indexer: An indexer is a property that receives an argument inside square brackets. Hashtable returns plain objects so you must cast them.
IndexerC# program that uses Contains method
using System;
using System.Collections;
class Program
{
static Hashtable GetHashtable()
{
// Create and return new Hashtable.
Hashtable hashtable = new Hashtable();
hashtable.Add("Area", 1000);
hashtable.Add("Perimeter", 55);
hashtable.Add("Mortgage", 540);
return hashtable;
}
static void Main()
{
Hashtable hashtable = GetHashtable();
// See if the Hashtable contains this key.
Console.WriteLine(hashtable.ContainsKey("Perimeter"));
// Test the Contains method.
// ... It works the same way.
Console.WriteLine(hashtable.Contains("Area"));
// Get value of Area with indexer.
int value = (int)hashtable["Area"];
// Write the value of Area.
Console.WriteLine(value);
}
}
Output
True
True
1000
Warning: This code might throw exceptions. Casting is a delicate operation. It is hard to get right.
Info: If the cast was applied to a different type, the statement could throw an InvalidCastException. We avoid this with "is" or "as."
C# program that uses multiple types
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);
}
}
Output
Carrot
1000
Is: You can also use the is-operator. This operator returns true or false based on the result.
IsAs: With Hashtable, you can reduce the number of casts by using the as-operator. This is a performance warning given by FxCop.
AsC# program that casts Hashtable values
using System;
using System.Collections;
using System.IO;
class Program
{
static void Main()
{
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);
}
}
}
Output
Blazer
is string: Blazer
Note: This Hashtable example uses the Keys property. This property returns all the keys.
Keys: The first loop in the program loops over the collection returned by the Keys instance property on the Hashtable instance.
Values: The second loop in the program shows how to enumerate only the values in the Hashtable instance.
ConsoleCopy: We create a new ArrayList with the copy constructor and pass it the Keys (or Values) property as the argument.
ArrayListC# program that loops over Keys, Values
using System;
using System.Collections;
class Program
{
static void Main()
{
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);
}
}
}
Output
800 (First loop)
600
500
400
Immolate (Second loop)
Fire
Fiery
Blaze
800 (Third loop)
600
500
400
Tip: An alternative to Clear() is to reassign your Hashtable reference to a new Hashtable().
Note: Microsoft states that, for Count, "retrieving the value of this property is an O(1) operation."
Time: Count is a constant-time accessor. It returns an integer and is a simple accessor with low resource demands.
C# program that uses Count
using System;
using System.Collections;
class Program
{
static void Main()
{
// Add four elements to Hashtable.
Hashtable hashtable = new Hashtable();
hashtable.Add(1, "Sandy");
hashtable.Add(2, "Bruce");
hashtable.Add(3, "Fourth");
hashtable.Add(10, "July");
// 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);
}
}
Output
4
0
Version 1: This version of the code uses the Hashtable from System.Collections and calls ContainsKey in a loop.
Version 2: This code uses ContainsKey from the generic Dictionary collection. It searches for the same keys.
Result: Hashtable is slower than the Dictionary code. Replacing code that uses Hashtable with Dictionary will likely make it faster.
C# program that benchmarks Hashtable, Dictionary
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
class Program
{
const int _max = 1000000;
static void Main()
{
// 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"));
Console.Read();
}
}
Output
66.99 ns Hashtable
51.22 ns Dictionary
However: If you need to look at all the keys and values in pairs, it is best to enumerate the Hashtable instance itself.