Table of Contents

    Understanding Hashtables: Efficient Data Storage and Retrieval

    A Hashtable is a collection of key/value pairs that are arranged based on the hash code of the key. Or in other words, a Hashtable is used to create a collection which uses a hash table for storage. It generally optimized the lookup by calculating the hash code of every key and store into another basket automatically and when you accessing the value from the hashtable at that time it matches the hashcode with the specified key. It is the non-generic type of collection which is defined in System.Collections namespace. 

    Important Points: 

    • In Hashtable, the key cannot be null, but value can be.
    • In Hashtable, key objects must be immutable as long as they are used as keys in the Hashtable.
    • The capacity of a Hashtable is the number of elements that Hashtable can hold.
    • A hash function is provided by each key object in the Hashtable.
    • The Hashtable class implements the IDictionaryICollectionIEnumerableISerializableIDeserializationCallback, and ICloneable interfaces.
    • In hashtable, you can store elements of the same type and of the different types.
    • The elements of hashtable that is a key/value pair are stored in DictionaryEntry, so you can also cast the key/value pairs to a DictionaryEntry.
    • In Hashtable, key must be unique. Duplicate keys are not allowed.

    Creating a Hashtable

    The following example demonstrates creating a Hashtable and adding elements.

    using System;
    using System.Collections;
    	
    public class Program
    {
    	public static void Main()
    	{
    		Hashtable numberNames = new Hashtable();
    		numberNames.Add(1,"One"); //adding a key/value using the Add() method
    		numberNames.Add(2,"Two");
    		numberNames.Add(3,"Three");
    
    		//The following throws run-time exception: key already added.
    		//numberNames.Add(3, "Three"); 
    
    		foreach(DictionaryEntry kvp in numberNames)
    			Console.WriteLine("Key: {0}, Value: {1}", kvp.Key, kvp.Value);
    
    		//creating a dictionary using collection-initializer syntax
    		var cities = new Hashtable(){
    			{"UK", "London, Manchester, Birmingham"},
    			{"USA", "Chicago, New York, Washington"},
    			{"India", "Mumbai, New Delhi, Pune"}
    		};
    
    		foreach(DictionaryEntry kvp in cities)
    			Console.WriteLine("Key: {0}, Value: {1}", kvp.Key, kvp.Value);		
    
    	}
    }

    Output

    Key: 3, Value: Three
    Key: 2, Value: Two
    Key: 1, Value: One
    Key: India, Value: Mumbai, New Delhi, Pune
    Key: UK, Value: London, Manchester, Birmingham
    Key: USA, Value: Chicago, New York, Washington

    The Hashtable collection can include all the elements of Dictionary, as shown below.

    using System;
    using System.Collections;
    using System.Collections.Generic;
    
    public class Program
    {
    	public static void Main()
    	{
    		Dictionary dict = new Dictionary();
    		
    		dict.Add(1, "one");
    		dict.Add(2, "two");
    		dict.Add(3, "three");
    		
    		Hashtable ht = new Hashtable(dict);
    		
    		Console.WriteLine("Total elements: {0}", ht.Count);
    		
    	}
    }

    Output

    Total elements: 3

    Update Hashtable

    You can retrieve the value of an existing key from the Hashtable by passing a key in indexer. The Hashtable is a non-generic collection, so you must type cast values while retrieving it.

    using System;
    using System.Collections;
    					
    public class Program
    {
    	public static void Main()
    	{
    		//creating a Hashtable using collection-initializer syntax
    		var cities = new Hashtable(){
    			{"UK", "London, Manchester, Birmingham"},
    			{"USA", "Chicago, New York, Washington"},
    			{"India", "Mumbai, New Delhi, Pune"}
    		};
    
    		string citiesOfUK = (string) cities["UK"]; //cast to string
    		string citiesOfUSA = (string) cities["USA"]; //cast to string
    
    		Console.WriteLine(citiesOfUK);
    		Console.WriteLine(citiesOfUSA);
    
    		cities["UK"] = "Liverpool, Bristol"; // update value of UK key
    		cities["USA"] = "Los Angeles, Boston"; // update value of USA key
    
    		if(!cities.ContainsKey("France")){
    			cities["France"] = "Paris";
    		}
    		
    		Console.WriteLine("---After updating values---");
    		
    		foreach(DictionaryEntry de in cities)
    			Console.WriteLine("key: {0}, Value: {1}", de.Key, de.Value);
    
    	}
    }

    Output

    London, Manchester, Birmingham
    Chicago, New York, Washington
    ---After updating values---
    key: India, Value: Mumbai, New Delhi, Pune
    key: UK, Value: Liverpool, Bristol
    key: France, Value: Paris
    key: USA, Value: Los Angeles, Boston

    Remove Elements in Hashtable

    The Remove() method removes the key-value that match with the specified in the Hashtable. It throws the KeyNotfoundException if the specified key not found in the Hashtable, so check for an existing key using the ContainsKey() method before removing.

    Use the Clear() method to remove all the elements in one shot.

    using System;
    using System.Collections;
    
    public class Program
    {
    	public static void Main()
    	{
    		var cities = new Hashtable(){
    			{"UK", "London, Manchester, Birmingham"},
    			{"USA", "Chicago, New York, Washington"},
    			{"India", "Mumbai, New Delhi, Pune"}
    		};
    
    		Console.WriteLine("Total Elements: {0}", cities.Count);
    		
    		cities.Remove("UK"); // removes UK 
    		//cities.Remove("France"); //throws run-time exception: KeyNotFoundException
    
    		Console.WriteLine("Total Elements: {0}", cities.Count);
    		
    		if(cities.ContainsKey("France")){ // check key before removing it
    			cities.Remove("France");
    		}
    
    		cities.Clear(); //removes all elements
    		Console.WriteLine("Total Elements after Clear(): {0}", cities.Count);
    
    	}
    }

    Output

    Total Elements: 3
    Total Elements: 2
    Total Elements after Clear(): 0

    Difference between Hashtable and Dictionary

    The following table lists the differences between Hashtable and Dictionary in C#.

    Hashtable Dictionary
    Hashtable is included in the System.Collections namespace. Dictionary is included in the System.Collections.Generic namespace.
    Hashtable is a loosely typed (non-generic) collection, this means it stores key-value pairs of any data types. Dictionary is a generic collection. So it can store key-value pairs of specific data types.
    Hashtable is thread safe. Only public static members are thread safe in Dictionary.
    Hashtable returns null if we try to find a key which does not exist. Dictionary throws an exception if we try to find a key which does not exist.
    Data retrieval is slower than dictionary because of boxing-unboxing. Data retrieval is faster than Hashtable.