December 18, 2013

C# Collections Part 3 : List, Hashtable and Dictionary

This post is dedicated to some phenomenal data structures that are available in C#. In most of your projects, you will find that any of these 3 data structures prove to be tremendously useful under any circumstance.

List: If you are familiar with ArrayList, you are already halfway down to understanding Lists. List is a generic class. The actual notation for a List class is List<T>. It's a template for any object type. Lets jump over to the code and see how to use a list.

using System;
using System.Collections.Generic;

namespace Spells
{
    class Program
    {
        static void Main(string[] args)
        {
            List<string> myStringList = new List<string>();
            myStringList.Add("Thoughts");
            /* myStringList.Add(1);    // this is error because it only support string type now */
            myStringList.Add("Spells");

            Console.WriteLine("Number of items {0}", myStringList.Count);
            foreach (string item in myStringList)   
            {
                Console.WriteLine("{0}", item);
            }

            myStringList.Insert(1, "Collections");   //inserts at index 1

            Console.WriteLine("Number of items {0}", myStringList.Count);
            foreach (string item in myStringList)
            {
                Console.WriteLine("{0}", item);
            }

            myStringList.Remove("Spells");   // removes the element "Spells"
            myStringList.RemoveAt(0);      // removes the element at index 0

            Console.WriteLine("Number of items {0}", myStringList.Count);
            foreach (string item in myStringList)
            {
                Console.WriteLine("{0}", item);
            }

            Console.Read(); //keeps the console alive
        }
    }
}
You will notice that the using statement at line 2 is slightly different than what we saw in the earlier posts. Here is the output console.
Console output
  1. Line 10 is the creation of a list object. Inside the angle bracket <> we have specified that our list object should contain only string data types. For the same reason, line 12 will generate an error because you are trying to add an integer object. This is a basic difference between List<T> and ArrayList.
  2. Added two string objects on line 11 and 13.
  3. Line 15 shows how many items are currently inside the list. Once you run this program, you will notice that there are 2 string items inside. Line 16 to 19 prints out each items. Pay attention! You know for sure that the list object contains only string objects. The foreach construct iterates through each item. You could not do that in ArrayList. Because ArrayList is not generic class. You would have to use object class to iterate each item inside the arraylist. This is another difference between ArrayList and List<T>.
  4. Line 21 is another way of adding items to the list. But you should be careful and know the difference between insert and add methods. The Add method adds items at the back of the list. But Insert method can add items anywhere in the list. By inserting an item anywhere in the middle, you slide down rest of the items and insert the current item at the desired index. As you can see in the output console, the number of items increased by 1 and item "Spells" slided down to make way for "Collections" at index 1.
  5. You can delete items just as you insert or add the items. Line 29 and 30 uses two different methods, one specifying the string items directly, while another trying to delete the item at the specific index. So what happens when you have duplicate items? Yes obviously List<T> can hold duplicate items. But which one gets deleted? Or both? The item belonging to the lower index gets deleted.
The bottom line is, List<T> is more preferable than ArrayList. Because its type safe. By type safe, it means that you do not have to worry about boxing and unboxing objects. If you are not familiar with boxing and unboxing, go ahead and read this post.

Hashtable: A Hashtable data structure is essentially a Dictionary. Currently Hashtable is less preferable than a more generic Dictionary<Tkey,Tvalue> class. However, for the sake of understanding data structures, I have decided to cover it here.

Dictionaries are used to associate values with a key. A key-value pair item helps you to look-up a value very quickly and its efficient as well. Be aware that keys must be unique. There is no sense of order in Dictionaries. The Hastable class is a remarkable example of Dictionary in C#. Lets jump over to a code snippet.

using System;
using System.Collections;

namespace Spells
{
    class Program
    {
        static void Main(string[] args)
        {
            Hashtable myHt = new Hashtable();

            myHt.Add("CSE 101", "Introduction to C");  // string key and string value
            myHt.Add("CSE 201", "Concepts of OOP: C# and .NET");  // string key and string value
            myHt.Add(5, "The key is an integer");   // integer key and string value
            myHt.Add("String key", 7);   // string key and integer value
            myHt["another key"] = "another way to insert value";  // string key and string value

            Console.WriteLine("Number of items {0}", myHt.Count);
            Console.WriteLine("Do you have CSE 201 key? {0}", myHt.ContainsKey("CSE 201"));
            myHt.Remove("String key");   // removes the key and the value
            Console.WriteLine("Do you have the value 7 ? {0}", myHt.ContainsValue(7));

            Console.Read(); //keeps the console alive
        }
    }
}
A Hashtable object is created just like you create objects for any other classes. On line 10 we create a Hashtable object. The Hashtable class is not a generic type. As much as that is a concern, you can create entries in many different possible ways as shown from line 12 to 16. Any data type can be the key and any data type can be the value, as long as the keys remain unique. Here is a visual console output window.
Console Output for Hashtable
Line 18 displays the number of current items inside the Hashtable. There are certain useful methods. Line 19 uses a method ContainsKey that takes as argument a key. It's a boolean method, it returns true if the key is in the table, else it will return false. We remove an item that we inserted at line 15 on line 20. That is why the output on line 21 shows that it cannot find the value 7 inside the Hashtable.

Dictionary<Tkey,Tvalue>: The only thing different here is that this class is generic. You can specify which data type is the key and which data type is the value. That way, you won't be able to mess around different data types at the same time. The boxing and unboxing issue is present here as well. There are other differences as well which are quite advanced, but worth knowing. We keep that until the end of this post.

Moving forward, lets see an example code snippet.

using System;
using System.Collections.Generic;

namespace Spells
{
    class Program
    {
        static void Main(string[] args)
        {
            Dictionary<string, string> courseTable = new Dictionary<string, string>();

            courseTable.Add("CSE 101", "Introduction to C");
            courseTable.Add("CSE 201", "Concepts of OOP: C# and .NET");
            courseTable.Add("CSE 207", "Data Structures and Algorithms");

            Console.WriteLine("Number of items {0}", courseTable.Count);
            foreach (KeyValuePair<string,string> pair in courseTable)
            {
                Console.WriteLine("Course Code: {0}, Course Title: {1}", pair.Key, pair.Value);
            }

            if (courseTable.ContainsKey("CSE 101"))
            {
                courseTable["CSE 101"] = "Introduction to Structured Programming";
            }
            if (!courseTable.ContainsValue("Database Systems"))
            {
                courseTable["CSE 301"] = "Database Systems";
            }

            Console.WriteLine("Number of items {0}", courseTable.Count);
            foreach (KeyValuePair<string, string> pair in courseTable)
            {
                Console.WriteLine("Course Code: {0}, Course Title: {1}", pair.Key, pair.Value);
            }
            
            Console.Read(); //keeps the console alive
        }
    }
}
I preferred to create a course table data structure so I opted for a string key and string value. The basic idea is you can create differently as you wish.
Console Output for Dictionary
  • Line 10 shall prove convincingly to you why Dictionary class is quite safer than Hashtable. You are not able to mess with types in Dictionary.
  • Line 12 to 14 creates 3 entries in the courseTable.
  • Line 16 to 20 are console outputs. Line 17 will give you something new to learn. .NET provides to you a safer way to iterate each key-value pair. You should keep in mind that the data types inside the angle bracket < > should match with the data types of the Dictionary object. The Key and Value properties enables you to work with these items.
  • While you decide to create new items or edit an existing items, its always safer to check if that item exists or not. That is what we are doing at line 22 and 26. If it happens that you are trying to edit/remove an item that never existed, then the C# compiler will throw an exception, unlike Hashtable that returns null in these cases. 
  • You can follow similar manners while removing an item.
There are some thread safety issues with Hashtable and Dictionary classes. Hashtable provides a thread safe environment where concurrent reads are handled nicely. In case of Dictionary, you will have to synchronize your reads and writes if you have multiple threads reading/writing them. The dictionary offers a bit more faster lookups because of value types.

I hope this post makes sense to you. Play with them and discover the undiscovered! Happy Coding!

No comments:

Post a Comment