December 16, 2013

C# Collections Part 1 : Array and ArrayList

We have already seen the C# data types and how they are declared and why each of them are internally dealt as an object. In this post, we shall learn about a bunch of these data types, called collections and how these collections are dealt with.

Arrays: In C#, arrays hold a fixed number of elements, all of the same type. For example, if you want a bunch of integer storage, we call them an integer array. If you want to hold a bunch of strings, we call them a string array.
Lets look at the following lines in the code snippet.

int oneInt;
oneInt = 45;
int[] manyInt = new int[5];
Line 1 creates an integer variable and we can assume that somewhere in the memory, the C# compiler creates some space for this variable and stores the value. On line 3, we are creating an integer array. If you are familiar with Java, this is no different than what you have experienced before. It might seem a bit untidy if you are jumping from C or C++. Line 3 is what we are currently interested about. It creates an array of integers, each of them can act similar to the oneInt variable. Somewhere in the memory, the C# compiler creates space for 5 integers in succession. The compiler automatically initializes them with value 0. That is,
  • manyInt[0] initializes to 0.
  • manyInt[1] initializes to 0.
  • manyInt[2] initializes to 0.
  • manyInt[3] initializes to 0.
  • manyInt[4] initializes to 0.
Notice that the numbers inside the square bracket starts at 0 and ends at 1 minus the number that you have specified while defining the array. That means that arrays have 0 based indexes.

In a similar way, you can create arrays of different data types, for example string, char, byte, short, long etc. Lets learn from an example.

using System;

namespace Spells
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] manyString = new string[4];
            manyString[0] = "This is string 1";
            manyString[1] = "This is string 2";
            manyString[2] = "This is string 3";
            manyString[3] = "This is string 4";

            for (int i = 0; i < manyString.Length; i++)
            {
                Console.WriteLine("{0}", manyString[i]);
            }
            Console.Read(); //keeps the console alive
        }
    }
}
As you can see, we have defined an array of type strings. We have used a for loop on line 15. Take a good look on the condition part. manyString.Length will give you the size/length of the array. You can understand from your previous experience that Length in this case is a property. On the outside we may already know the size of the array, but there will be cases when you are not sure about the size of the array. The Length property is really handy in this case.
There is in fact another elegant way of accessing all the items inside an array. Look at the following code. Copy and paste this code instead of the previous for loop.

foreach (string str in manyString)
{
    Console.WriteLine("{0}", str);   
}
We have previously skipped this foreach loop. This special construct of for loop is very handy in handling array items. The "string str" part says that each of the items are individually string type, that's obvious right? The "in manyString" statement says that we are looking for the individual string type "things" inside the manyString array.

We can initialize an array. For example, these two lines are perfectly valid and okay.

int[] myInt = {4,7,2,9,15};
string[] myString = {"One","Two","Three"};
The first line creates an integer array containing 5 elements, while the second line creates a string array containing three elements. The C# compiler will automatically calculate the size of the arrays.

Bounds checking: One of the cool features of C# array is that it can automatically check the array bounds for you. Bounds checking means the C# compiler will keep a notice if you are trying to access an index beyond the size of the array. Keep in mind that in case of arrays, once you declare and define the size of the array, that is how big they can be, you cannot change or modify this size after that. So arrays are fixed in size. It might seem to you a little bit disadvantageous. But once you know that you need certain numbers of elements in an array, the compiler allows them to be contiguous in memory. This is advantageous and very efficient. So bound checking is important. For example, the following code will generate error.

using System;

namespace Spells
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] manyString = new string[4];
            manyString[0] = "This is string 1";
            manyString[1] = "This is string 2";
            manyString[2] = "This is string 3";
            manyString[3] = "This is string 4";

            foreach (string str in manyString)
            {
                Console.WriteLine("{0}", str);   
            }
            manyString[10] = "This is an error";
            Console.WriteLine("{0}",manyString[99]);
            Console.Read(); //keeps the console alive
        }
    }
}
Lines 19 and 20 are both erroneous.

Multidimensional Array: Arrays can have multiple dimensions. Here is an example of a two dimensional array.
Two dimensional Array
You can access any element, for example the 1st element on row 2 can be accessed simply writing multiArray[1,0]. 

Array Functions: You are aware that almost everything in C# is an object. You also know that you can access static methods inside a class without creating object of that class. Having said that, look at the following code snippet.

using System;

namespace Spells
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] myints = { 5, 9, 3, 4, 1, 10, 8 };
            Array.Sort(myints);   //sorts the array
            foreach (int item in myints)
            {
                Console.WriteLine("{0}",item);
            }

            Array.Clear(myints, 0, 3);  //clears the first 3 elements starting at index 0
            foreach (int item in myints)
            {
                Console.WriteLine("{0}", item);
            }

            Array.Reverse(myints);  //reverses the current order of the array
            foreach (int item in myints)
            {
                Console.WriteLine("{0}", item);
            }
            Console.Read(); //keeps the console alive
        }
    }
}
Here is a basic demonstration of some of the built-in facilities that .NET provides for you. Line 9 declares an integer array. Array is a class provided by the .NET framework. This class contains some useful static methods. You obviously understand that static methods can called by the class definition.
  1. Line 10 sorts the array. You can see that sorted output on the following foreach loop.
  2. Line 16 is helpful when you need to reinitialize (make the elements 0 again) a sequence of elements inside the array. The 1st argument takes the name of the array, the 2nd argument asks for the index where we want to start clearing and the 3rd argument takes the number of consecutive elements that we want to clear.
  3. Line 22 reverses the order of array elements.
There are a lot other useful functions that you may explore yourself.

ArrayList: ArrayLists are like arrays, but they can be dynamically resized on the fly, unlike arrays. ArrayLists are flexible in a number of ways. For example, consider the following code.

using System;
using System.Collections;

namespace Spells
{
    class Program
    {
        static void Main(string[] args)
        {
            ArrayList arrList = new ArrayList();
            arrList.Add(5);   // 5 is an integer object
            arrList.Add("Thoughts and Spells");  // string object
            arrList.Add('G');  // character object
            for (int i = 0; i < arrList.Count; i++)
            {
                Console.WriteLine("{0}", arrList[i]);
            }
            Console.Read(); //keeps the console alive
        }
    }
}
An ArrayList is created by an object of ArrayList class. This is what we are doing at line 10. Observe that in order to use ArrayList class, we had to add another using statement at line 2. Consider line 11 to 13. We have added 3 different types of objects. Keep in mind that the elements inside the ArrayLists are treated as objects. And this is very clear to us that almost everything in C# is an object.
We have already found two major issues that proves ArrayList as a preferable data structure over Arrays. Firstly the size is dynamic, you can add as many elements as you wish. Secondly, you can add any types of objects, you don't have to worry about the types.

Moving on, consider line 14. Count is a property that returns the current number of elements inside the ArrayList. Do keep in mind that ArrayLists have 0 based indexes. Here are some useful functions.

arrList.Insert(index,object);  // inserts the object in the given index
arrList.Remove(object);  // Deletes the object
arrList.RemoveAt(index);  //Deletes the object in the given index
int index = arrList.IndexOf(object);  // Returns the index where the given object is present

Go ahead and use them in your projects. We shall continue with newer collections in the next post.

No comments:

Post a Comment