We have learned about an array in the previous section. C# also includes specialized classes that hold many values or objects in a specific series, that are called 'collection'.
There are two types of collections available in C#: non-generic collections and generic collections. We will learn about non-generic collections in this section.
The System.Collections namespace includes the interfaces and classes for the non-generic collections. The following diagram illustrates the hierarchy of the interfaces and classes for the non-generic collections.
C# Collections
As you can see in the above diagram, IEnumerator, IEnumerable, and ICollection are the top level interfaces for all the collections in C#.
IEnumerator: The IEnumerator interface supports a simple iteration over a non-generic collection. It includes methods and property which can be implemented to support easy iteration using foreach loop.
IEnumerable: The IEnumerable interface includes GetEnumerator() method which returns an object of IEnumerator.
So, all the built-in collection classes and custom collection classes must implement IEnumerator and IEnumerable interfaces for easy iteration using foreach loop.
ICollection: The ICollection interface is the base interface for all the collections that defines sizes, enumerators, and synchronization methods for all non-generic collections. The Queue and Stack collection implement ICollection inferface.
IList: The IList interface includes properties and methods to add, insert, remove elements in the collection and also individual element can be accessed by index. The ArrayList and BitArray collections implement IList interface.
IDictionary: The IDictionary interface represents a non-generic collection of key/value pairs. The Hashtable and SortedList implement IDictionary interface and so they store key/value pairs.
As you can see from the diagram, ArrayList, BitArray, Hashtable, SortedList, Queue, and Stack collections implement different interfaces and so, they are used for the different purposes.
ArrayList stores objects of any type like an array. However, there is no need to specify the size of the ArrayList like with an array as it grows automatically.
SortedList stores key and value pairs. It automatically arranges elements in ascending order of key by default. C# includes both, generic and non-generic SortedList collection.
Stack stores the values in LIFO style (Last In First Out). It provides a Push() method to add a value and Pop() & Peek() methods to retrieve values. C# includes both, generic and non-generic Stack.
Queue stores the values in FIFO style (First In First Out). It keeps the order in which the values were added. It provides an Enqueue() method to add values and a Dequeue() method to retrieve values from the collection. C# includes generic and non-generic Queue.
Hashtable stores key and value pairs. It retrieves the values by comparing the hash value of the keys.
BitArray
BitArray manages a compact array of bit values, which are represented as Booleans, where true indicates that the bit is on (1) and false indicates the bit is off (0).
Let's see each type of collection in the next chapters.
C# - ArrayList
ArrayList is a non-generic type of collection in C#. It can contain elements of any data types. It is similar to an array, except that it grows automatically as you add items in it. Unlike an array, you don't need to specify the size of ArrayList.
The following diagram illustrates the ArrayList class hierarchy.
C# ArrayList
As you can see from the above diagram, the ArrayList class implements IEnumerable, ICollection, and IList interfaces. So, you can create an object of ArrayList class and assign it to the variable of any base interface type. However, if you assign it to IEnumerable or ICollection type variable then you won't be able to add elements and access ArrayList by index.
Example: Create ArrayList
ArrayList myArryList1 = newArrayList();// Recommended// or - with some limitationsIList myArryList2 = newArrayList();
// or - with some limitationsICollection myArryList3 = newArrayList();
// or - with some limitationsIEnumerable myArryList4 = newArrayList();
It is recommended to use ArrayList type of variable for ArrayList object because ArrayList class contains some additional methods which are not the members of IListinterface such as AddRange(), BinarySearch(), Repeat(), Reverse(), etc.
Important Properties and Methods of ArrayList
Properties
Description
Capacity
Gets or sets the number of elements that the ArrayList can contain.
Count
Gets the number of elements actually contained in the ArrayList.
IsFixedSize
Gets a value indicating whether the ArrayList has a fixed size.
IsReadOnly
Gets a value indicating whether the ArrayList is read-only.
Insert() method insert a single elements at the specified index in ArrayList. InsertRange() method insert all the elements of the specified collection starting from specified index in ArrayList.
Checks whether specified element exists in the ArrayList or not. Returns true if exists otherwise false.
Clear
Removes all the elements in ArrayList.
CopyTo
Copies all the elements or range of elements to compitible Array.
GetRange
Returns specified number of elements from specified index from ArrayList.
IndexOf
Search specified element and returns zero based index if found. Returns -1 if element not found.
ToArray
Returns compitible array from an ArrayList.
Adding Elements into ArrayList
The AddRange() method can take any type of collection that implements the ICollection interface e.g. List, ArrayList, SortedList, Queue, Stack, HashSet, Hashtable, etc.
Use the Add()method to add a single element or the AddRange() method to add multiple elements from the other collections into an ArrayList. Here, the element means the literal value of a primitive or non-primitive type. Please note that the AddRange() method only available in the ArrayList class but not in IList. So, it can only be use with the variable of type ArrayList.
Signature: int Add(Object value) void AddRange(ICollection c)
Example: Adding Elements into ArrayList
ArrayList arryList1 = newArrayList();
arryList1.Add(1);
arryList1.Add("Two");
arryList1.Add(3);
arryList1.Add(4.5);
IList arryList2 = newArrayList()
{
100, 200
};
//Adding entire collection using ArrayList.AdRange() method.////Note: IList does not contain AddRange() method.
arryList1.AddRange(arryList2);
You can also add items when you initialize it using object initializer syntax.
ArrayList can contain multiple null and duplicate values.
Accessing Elements
ArrayList elements can be accessed using indexer, in the same way as an array. However, you need to cast it to the appropriate type or use the implicit type varkeyword while accessing it.
Use a foreach or a for loop to iterate an ArrayList.
Example: Iterate ArrayList
IList myArryList = newArrayList()
{
1,
"Two",
3,
4.5F
};
foreach (var val in myArryList)
Console.WriteLine(val);
//Orfor(int i = 0 ; i< myArryList.Count; i++)
Console.WriteLine(myArryList[i]);
Output:
1 Two 3 4.5
Inserting Elements into ArrayList
Use the IList.Insert() method to insert a single item at the specified index.
Signature: void Insert(int index, Object value)
Example: Insert()
IList myArryList = newArrayList();
myArryList.Add(1);
myArryList.Add("Two");
myArryList.Add(3);
myArryList.Add(4.5);
myArryList.Insert(1, "Second Item");
myArryList.Insert(2, 100);
foreach (var val in myArryList)
Console.WriteLine(val);
Use the ArrayList.InsertRange() method to insert all the values from another collection into ArrayList at the specfied index. Please note that the InsertRange()method only available in the ArrayList class but not in IList. So, it can only be use with the variable of type ArrayList.
Signature: Void InsertRange(int index, ICollection c)
Use the IList.Remove() method to remove a specified element from an ArrayList.
Signature: void Remove(Object obj)
Example: Remove()
IList arryList1 = new ArrayList();
arryList1.Add(100);
arryList1.Add(200);
arryList1.Add(300);
arryList1.Remove(100); //Removes 1 from ArrayListforeach (var item in arryList1)
Console.WriteLine(item);
Output:
200 300
Use the IList.RemoveAt() method to remove an element from the specified index location.
Signature: void RemoveAt(int index)
Example: RemoveAt()
IList arryList1 = new ArrayList();
arryList1.Add(100);
arryList1.Add(200);
arryList1.Add(300);
arryList1.RemoveAt(1); //Removes the first element from an ArrayListforeach (var item in arryList1)
Console.WriteLine(item);
Output:
100 300
Use the ArrayList.RemoveRange() method to remove multiple elements from the specified index till the specified number of elements in the ArrayList. Please note that the RemoveRange() method only available in the ArrayList class but not in IList. So, it can only be use with the variable of type ArrayList.
Signature: void RemoveRange(int index, int count)
Example: RemoveRange()
ArrayList arryList1 = new ArrayList();
arryList1.Add(100);
arryList1.Add(200);
arryList1.Add(300);
arryList1.RemoveRange(0,2);//Removes two elements starting from 1st item (0 index)foreach(var item in arryList1)
Console.WriteLine(item);
Output:
300
ArrayList Sorting
The ArrayList class includes Sort() and Reverse() method. The Sort() method arranges elements in ascending order. However, all the elements should have same data type so that it can compare with default comparer otherwise it will throw runtime exception.
The Reverse() method arranges elements in reverse order. Last element at zero index and so on.
Example: Sort(), Reverse()
ArrayList arryList1 = new ArrayList();
arryList1.Add(300);
arryList1.Add(200);
arryList1.Add(100);
arryList1.Add(500);
arryList1.Add(400);
Console.WriteLine("Original Order:");
foreach(var item in arryList1)
Console.WriteLine(item);
arryList1.Reverse();
Console.WriteLine("Reverse Order:");
foreach(var item in arryList1)
Console.WriteLine(item);
arryList1.Sort();
Console.WriteLine("Ascending Order:");
foreach(var item in arryList1)
Console.WriteLine(item);
Check for an Existing Elements in ArrayList
The IList.Contains() method checks whether specified element exists in the ArrayList or not. Returns true if exists otherwise false.
ArrayList can store items(elements) of any datatype.
ArrayList resizes automatically as you add the elements.
ArrayList values must be cast to appropriate data types before using it.
ArrayList can contain multiple null and dulplicate items.
ArrayList can be accessed using foreach or for loop or indexer.
Use Add(), AddRange(), Remove(), RemoveRange(), Insert(), InsertRange(), Sort(), Reverse() methods.
C# - SortedList
The SortedList collection stores key-value pairs in the ascending order of key by default. SortedList class implements IDictionary & ICollection interfaces, so elements can be accessed both by key and index.
C# includes two types of SortedList, generic SortedList and non-generic SortedList. Here, we will learn about non-generic SortedList.
The following diagram illustrates the non-generic SortedList hierarchy.
C# SortedList
Important Properties and Methods of SortedList
Property
Description
Capacity
Gets or sets the number of elements that the SortedList instance can store.
Count
Gets the number of elements actually contained in the SortedList.
IsFixedSize
Gets a value indicating whether the SortedList has a fixed size.
IsReadOnly
Gets a value indicating whether the SortedList is read-only.
Item
Gets or sets the element at the specified key in the SortedList.
Keys
Get list of keys of SortedList.
Values
Get list of values in SortedList.
Method
Description
Add(object key, object value)
Add key-value pairs into SortedList.
Remove(object key)
Removes element with the specified key.
RemoveAt(int index)
Removes element at the specified index.
Contains(object key)
Checks whether specified key exists in SortedList.
Clear()
Removes all the elements from SortedList.
GetByIndex(int index)
Returns the value by index stored in internal array
GetKey(int index)
Returns the key stored at specified index in internal array
IndexOfKey(object key)
Returns an index of specified key stored in internal array
IndexOfValue(object value)
Returns an index of specified value stored in internal array
Add elements in SortedList
Use the Add() method to add key-value pairs into a SortedList.
Internally, SortedList maintains two object[] array, one for keys and another for values. So when you add key-value pair, it runs a binary search using the key to find an appropriate index to store a key and value in respective arrays. It re-arranges the elements when you remove the elements from it.
SortedList collection sorts the elements everytime you add the elements. So if you debug the above example, you will find keys in ascending order even if they are added randomly, as below:
SortedList in debug view
Please notice that sortedList2 sorts the key in alphabetical order for string key in the above image.
SortedList key can be of any data type, but you cannot add keys of different data types in the same SortedList. The key type of the first key-value pair remains the same for all other key-value pairs. The following example will throw run time exception because we are trying to add the second item with a string key:
Example: Key of different datatypes throws exception:
SortedList can be accessed by index or key. Unlike other collection, SortedList requires key instead of index to access a value for that key.
Example: Access SortedList
SortedList sortedList = new SortedList()
{
{"one", 1},
{"two", 2},
{"three", 3},
{"four", "Four"}
}
int i = (int) sortedList["one"];
int j = (int) sortedList["two"];
string str = (string) sortedList["four"];
Console.WriteLine(i);
Console.WriteLine(j);
Console.WriteLine(str);
Output:
1 2 Four
Note:
Non-generic SortedList collection can contain key and value of any data type. So values must be cast to the appropriate data type otherwise it will give compile-time error.
Use for loop to access SortedList as shown below.
Example: Accessing Values using For Loop
SortedList sortedList = new SortedList()
{
{3, "Three"},
{4, "Four"},
{1, "One"},
{5, "Five"},
{2, "Two"}
};
for (int i = 0; i < sortedList.Count; i++)
{
Console.WriteLine("key: {0}, value: {1}",
sortedList.GetKey(i), sortedList.GetByIndex(i));
}
Output:
key: 1, value: One key: 2, value: Two key: 3, value: Three key: 4, value: Four key: 5, value: Five
The foreach statement can also be used to access the SortedList collection. SortedList includes key-value pairs. So, the type of element would be DictionaryEntry rather than the type of a key or a value.
Use the Remove() or RemoveAt() method to remove elements from a SortedList.
Remove() signature: void Remove(object key)
RemoveAt() signature: void RemoveAt(int index)
Example: Remove elements in SortedList
SortedList sortedList = new SortedList();
sortedList.Add("one", 1);
sortedList.Add("two", 2);
sortedList.Add("three", 3);
sortedList.Add("four", 4);
sortedList.Remove("one");//removes element whose key is 'one'
sortedList.RemoveAt(0);//removes element at zero index i.e first element: fourforeach(DictionaryEntry kvp in sortedList )
Console.WriteLine("key: {0}, value: {1}", kvp.Key , kvp.Value );
Output:
key: three, value: 3 key: two, value: 2
Check for an existing key in SortedList
The Contains() & ContainsKey() methods determine whether the specified key exists in the SortedList collection or not.
Visit MSDN for more information on the properties and methods of SortedList.
Points to Remember :
C# has generic and non-generic SortedList.
SortedList stores the key-value pairs in ascending order of the key. Key must be unique and cannot be null whereas value can be null or duplicate.
Non-generic SortedList stores keys and values of any data types. So values needs to be cast to appropriate data type.
Key-value pair can be cast to DictionaryEntry.
Access individual value using indexer. SortedList indexer accepts key to return value associated with it.
C# - Hashtable
C# includes Hashtable collection in System.Collections namespace, which is similar to generic Dictionary collection. The Hashtable collection stores key-value pairs. It optimizes lookups by computing the hash code of each key and stores it in a different bucket internally and then matches the hash code of the specified key at the time of accessing values.
The following diagram illustrates the Hashtable class hierarchy.
C# Hashtable
Important Propertis and Methods of Hashtable
Property
Description
Count
Gets the total count of key/value pairs in the Hashtable.
IsReadOnly
Gets boolean value indicating whether the Hashtable is read-only.
Item
Gets or sets the value associated with the specified key.
Checks whether the hashtable contains a specific value.
GetHash
Returns the hash code for the specified key.
Add key-value into Hashtable
The Add() method adds an item with a key and value into the Hashtable. Key and value can be of any data type. Key cannot be null whereas value can be null.
Note : Add() will throw an exception if you try to add a key that already exists in the Hashtable. So always check the key using the Contains() or ContainsKey() method before adding a key-value pair into the Hashtable.
Access Hashtable
You can retrive the value of an existing key from the Hashtable using indexer. Please note that the hashtable indexer requires a key.
Hashtable is a non-generic collection so it can contains a key and a value of any data type. So values must be cast to an appropriate data type otherwise it will give compile-time error.
Hashtable elements are key-value pairs stored in DictionaryEntry. So you cast each element in Hashtable to DictionaryEntry. Use the foreach statement to iterate the Hashtable, as shown below:
Contains() and ContainsKey() check whether the specified key exists in the Hashtable collection. ContainsValue() checks whether the specified value exists in the Hashtable.
Contains(), ContainsKey() and ContainsValue() Signatures:
C# includes a special type of collection which stores elements in LIFO style (Last In First Out). C# includes a generic and non-generic Stack. Here, you are going to learn about the non-generic stack.
Stack allows null value and also duplicate values. It provides a Push() method to add a value and Pop() or Peek() methods to retrieve values.
C# Stack
The following diagram illustrates the Stack class hierarchy.
The Peek() method returns the last (top-most) value from the stack. Calling Peek() method on empty stack will throw InvalidOperationException. So always check for elements in the stack before retrieving elements using the Peek() method.
You can also retrieve the value using the Pop() method. The Pop() method removes and returns the value that was added last to the Stack. The Pop() method call on an empty stack will raise an InvalidOperationException. So always check for number of elements in stack must be greater than 0 before calling Pop() method.
Pop() signature: object Pop();
Example: Access Stack
Stack myStack = newStack();
myStack.Push(1);
myStack.Push(2);
myStack.Push(3);
myStack.Push(4);
myStack.Push(5);
Console.Write("Number of elements in Stack: {0}", myStack.Count);
while (myStack.Count > 0)
Console.WriteLine(myStack.Pop());
Console.Write("Number of elements in Stack: {0}", myStack.Count);
Output:
Number of elements in Stack: 5 5 4 3 2 1 Number of elements in Stack: 0
Contains()
The Contains() method checks whether the specified item exists in a Stack collection or not. It returns true if it exists; otherwise it returns false.
The Clear() method removes all the values from the stack.
Clear() signature: void Clear();
Example: Stack.Contains()
Stack myStack = newStack();
myStack.Push(1);
myStack.Push(2);
myStack.Push(3);
myStack.Push(4);
myStack.Push(5);
myStack.Clear(); // removes all elementsConsole.Write("Number of elements in Stack: {0}", myStack.Count);
Output:
Number of elements in Stack: 0
Points to Remember :
Stack stores the values in LIFO (Last in First out) style. The element which is added last will be the element to come out first.
Use the Push() method to add elements into Stack.
The Pop() method returns and removes elements from the top of the Stack. Calling the Pop() method on the empty Stack will throw an exception.
The Peek() method always returns top most element in the Stack.
C# includes a Queue collection class in the System.Collection namespace. Queue stores the elements in FIFO style (First In First Out), exactly opposite of the Stack collection. It contains the elements in the order they were added.
Queue collection allows multiple null and duplicate values. Use the Enqueue() method to add values and the Dequeue() method to retrieve the values from the Queue.
The following diagram illustrates the Queue class hierarchy.
Dequeue() method is used to retrieve the top most element in a queue collection. Dequeue() removes and returns a first element from a queue because the queue stores elements in FIFO order. Calling Dequeue() method on empty queue will throw InvalidOperation exception. So always check that the total count of a queue is greater than zero before calling the Dequeue() method on a queue.
Dequeue() method signature: object Dequeue()
Example: Dequeue()
Queue queue = newQueue();
queue.Enqueue(3);
queue.Enqueue(2);
queue.Enqueue(1);
queue.Enqueue("Four");
Console.WriteLine("Number of elements in the Queue: {0}", queue.Count);
while (queue.Count > 0)
Console.WriteLine(queue.Dequeue());
Console.WriteLine("Number of elements in the Queue: {0}", queue.Count);
Output:
Number of elements in the Queue: 4 3 2 1 Four Number of elements in the Queue: 0
Peek()
The Peek() method always returns the first item from a queue collection without removing it from the queue. Calling Peek() and Dequeue() methods on an empty queue collection will throw a run time exception "InvalidOperationException".
Peek() Method Signature: object Peek();
Example: Peek()
Queue queue = newQueue();
queue.Enqueue(3);
queue.Enqueue(2);
queue.Enqueue(1);
queue.Enqueue("Four");
Console.WriteLine("Number of elements in the Queue: {0}", queue.Count);
Console.WriteLine(queue.Peek());
Console.WriteLine(queue.Peek());
Console.WriteLine(queue.Peek());
Console.WriteLine("Number of elements in the Queue: {0}", queue.Count);
Output:
Number of elements in the Queue: 4 3 3 3 Number of elements in the Queue: 4
You can iterate a Queue without removing elements of it by converting in to an Array, as below:
Example: Iterate Queue
Queue queue = newQueue();
queue.Enqueue(3);
queue.Enqueue(2);
queue.Enqueue(1);
queue.Enqueue("Four");
Console.WriteLine("Number of elements in Queue: {0}", queue.Count);
foreach (var i in queue.ToArray())
Console.WriteLine(i);
Console.WriteLine("Number of elements in Queue: {0}", queue.Count);
Output:
Number of elements in Queue: 4 3 2 1 Four Number of elements in Queue: 4
Contains()
The Contains() method checks whether an item exists in a queue. It returns true if the specified item exists; otherwise it returns false.
The Clear() method removes all the items from a queue.
Clear() Signature: void Clear();
Example: Clear()
Queue queue = newQueue();
queue.Enqueue(3);
queue.Enqueue(2);
queue.Enqueue(1);
queue.Enqueue("Four");
Console.WriteLine("Number of elements in the Queue: {0}", queue.Count);
queue.Clear();
Console.WriteLine("Number of elements in the Queue: {0}", queue.Count);
Output:
Number of elements in the Queue: 4 Number of elements in the Queue: 0
Visit MSDN for more information on members of Queue.
Points to Remember :
The Queue stores the values in FIFO (First in First out) style. The element which is added first will come out First.
Use the Enqueue() method to add elements into Queue
The Dequeue() method returns and removes elements from the beginning of the Queue. Calling the Dequeue() method on an empty queue will throw an exception.
The Peek() method always returns top most element.
No comments:
Post a Comment