Sunday, August 3, 2008

Choosing the right .Net Framework data collection

The .Net Framework includes several useful data collection classes; choosing the right one for the task at hand is greatly crucial. In the following, I will explain about some of the most useful collections available in Framework. So, you can easily decide which one to use in different situations.

These classes which are part of System.Collections namespace and System.Collections.Specialized are ArrayList, SortedList, Queue, Stack, Hashtable, BitArray, StringCollection, StringDictionary, ListDictionary, HybirdDictionary, and NameValueCollection.

ArrayList

ArrayList stores the data items of any object type in an unordered manner. Add method is used to add new data items to the collection as the last item. To add new items at a specific location, the class provides users with Insert method. You can use ArrayList numeric indexer to access each item in the collection or iterate over items. Also, you can use foreach for iteration of type object or a particular type in the case all the items are of that type (see the example for more details). Removing items from the collection is done by Remove and RemoveAt methods.

Other useful methods of ArrayList are:

Clear (empties the collection), IndexOf (specifies index of an item in the collection), Sort (sorts items in the collection), and Contains (verifies existence of an item in the collection).

Example:

Note: the example below requires System.Collections and System.Diagnostics namespaces.

ArrayList MyArrayList=new ArrayList();

MyArrayList.Add("New Item");

MyArrayList.Insert(0,"This is placed as the first item");

if (MyArrayList.Contains("New Item"))

{
    Debug.Write(MyArrayList.IndexO("New Item"))//Writes to output window. Run in debug mode.
    MyArrayList.Remove("New Item");
}

foreach (string EachItem in MyArrayList)
    System.Diagnostics.Debug.Write(EachItem )//Writes to output window. Run in debug mode.

MyArrayList.RemoveAt(0);
MyArrayList.Clear();

StringCollection

StringCollection is built to store only string items and not any other types of object. Working with StringCollection is similar to ArrayList.

Queue

The Queue stores objects in a first-in first-out manner. It means that the fist item added to the collection is the first item that is retrieved from it. Working with Queue is very simple; you can use Enqueue method to add new items, Dequeue method to retrieve items which removes the object from the collection as well, Peek method to extract the object without removing it from the collection, and Count property which returns the number of objects in the collection.

Example:

Note: the example below requires System.Collections and System.Diagnostics namespaces.

Queue MyQueue = new Queue();
MyQueue.Enqueue(2000);
MyQueue.Enqueue(new object());
MyQueue.Enqueue("Last Item");
Debug.WriteLine(MyQueue.Count);
if (MyQueue.Peek() is int)
    Debug.WriteLine(((int)MyQueue.Dequeue())+1);

Debug.WriteLine(MyQueue.Count);
MyQueue.Clear();

Stack

Stack is very similar to Queue the only difference is that Stack stores object in a last-in, first-out fashion. To work with the stored object Stack exposes Push method which adds new object to the collection, Pop method which extracts the object with removing it from the collection, Peek method which extracts the object without removing it from the collection, Clear method which removes all the objects, and Count property which shows the number of objects in the collection.

Example:

Note: the example below requires System.Collections and System.Diagnostics namespaces.

Stack MyStack = new Stack();
MyStack.Push(2000);
MyStack.Push(new object());
MyStack.Push("Last Item");
Debug.WriteLine(MyStack.Count);
if (MyStack.Peek() is string)
    Debug.WriteLine(string.Concat((string)MyStack.Pop()," is the first to be out."));

Debug.WriteLine(MyStack.Count);
MyStack.Clear();

Hashtable

Hashtable is a dictionary collection which means it keeps data in form of key and value pairs. Each collection entry is stored in one DictionaryEntry structure which in turn contains a key and a value. Key and value can be any object; a key cannot be null.  The primary purpose of dictionaries is to look up pairs.

Working with Hashtable is easy; you can use Add method to add new pairs, indexer to access each value, Remove method to remove a pair, ContainsKey method to verify existence of a key in the collection, ContainsValue to verify existence of a value in the collection, Keys property gets all the keys in the collection, Values property to get all the values in the collection, and Clear method to remove all the pairs from the collection.

Example:

Note: the example below requires System.Collections and System.Diagnostics namespaces.

Hashtable MyHashtable=new Hashtable();
MyHashtable.Add("MyKey1","MyValue");
MyHashtable.Add("MyKey2", DateTime.Now);

foreach (DictionaryEntry EachPair in MyHashtable)
    Debug.WriteLine(EachPair.Value);
if (MyHashtable.ContainsKey("MyKey1"))
    Debug.WriteLine(MyHashtable["MyKey1"]);
if (MyHashtable.ContainsValue("MyValue"))
    MyHashtable.Remove("MyKey1");

MyHashtable.Clear();

ListDictionary

ListDictionary is identical to HashTable in terms of interface but is more efficient for fewer than 10 items. See HashTable for an example on how to use this collection.

HybridDictionary

When the number of items is not known, HybirdDictionary can be used in place of HashTable or ListDictionary. HybridDictionary starts off internally as ListDictionary and converts to HashTable when the number of items in the collection gets higher than 10. HybirdDictionary also has the same interface as HashTable and ListDictionary. See HashTable for an example on how to use this collection.

OrderedDictionary

OrderedDictionary combines the power of arrays and dictionaries. In other words, working with it is much similar to HashTabe but it also provides users with properties and methods to allow items to be accessed by index. In addition to HashTable properties and methods, you can use Item property to access each item, Insert to add a new dictionary entry to a specific index in the collection, and RemoveAt to remove dictionary entries and a given index.

StringDictionary

StringDictionary is specialized dictionary collection that only stores string keys and values. Working with StringDictionary is the same as HashTable.

SortedList

Similar to Hashtable, SortedList is a dictionary collection and values are kept in key and value pairs. Therefore, all the above methods and properties for Hashtable also apply SortedList. In addition SortedList sorts the entries as soon as they are added to the collection and lets entries be accessed by index.  Note that index may change after adding or removing entries because the entries are sorted. 

Other useful methods of SortedList are IndexOfKey that returns index of a key in the collection, IndexOfValue that returns the first index of a value in the collection, GetKey that returns a key of a specific index, and GetByIndex that returns value of a specific index.

Example:

Note: the example below requires System.Collections and System.Diagnostics namespaces.

SortedList MySortedList = new SortedList();
MySortedList.Add("MyKey1","MyValue");
MySortedList.Add("MyKey2", DateTime.Now);

foreach (DictionaryEntry EachPair in MySortedList)
    Debug.WriteLine(EachPair.Value);

Debug.WriteLine(MySortedList.IndexOfKey("MyKey2"));
Debug.WriteLine(MySortedList.IndexOfValue("MyValue"));
Debug.WriteLine(MySortedList.GetKey(0));
Debug.WriteLine(MySortedList.GetByIndex(1));

if (MySortedList.ContainsKey("MyKey1"))
    Debug.WriteLine(MySortedList["MyKey1"]);
if (MySortedList.ContainsValue("MyValue"))
    MySortedList.Remove("MyKey1");

MySortedList.Clear();

BitArray

BitArray is a resizeable collection of bits and capable of performing boolean operations. To create a new instance you need to specify the length of the collection. This collection does not provide Add method; therefore, the only way to increase the capacity of it is through modification of its length property.

NameValueCollection

NameValueCollection is a dictionary collection that is able to store multiple values per key. All keys and values for this collection are of type string. To get values of a specific key, you can use GetValues method; also you can use index to access values of a key and since there can be more than one value per key, the collection returns a comma separated list of key values. You can use Add method to add new items and Clear method to remove all the items.

Example:

Note: the example below requires System.Collections.Specialized and System.Diagnostics namespaces.

NameValueCollection MyNameValueCollection = new NameValueCollection();
MyNameValueCollection.Add("FirstKey", "FirstKeyFirstValue");
MyNameValueCollection.Add("FirstKey", "FirstKeySecondValue");
MyNameValueCollection.Add("SecondKey", "SecondKeyFirstValue");
MyNameValueCollection.Add("SecondKey", "SecondKeySecondValue");
Debug.WriteLine(MyNameValueCollection.GetValues("FirstKey")[0]);
Debug.WriteLine(MyNameValueCollection.GetValues(1).Length);
Debug.WriteLine(MyNameValueCollection[1]);
MyNameValueCollection.Clear();

No comments: