Introduction to Collections |
|
Array-Based Lists |
A collection, also called a list, is many items of the same kind grouped into one entity. The collection can be based on simple numbers, basic symbols, dates, strings, times. The collection can also be made of objects that each is made of internal values. This means that a collection can be made of such objects as houses, people, cars, countries, electronic devices. |
The primary rule to observe is that all items included in a list must be described using the same characteristics. Based on this, if the collection is made of cars, it should contain only cars, not cars and countries. There are various types of lists or collections. An array-based list is one whose number of items is known in advance. For example, an array-based collection of 10 cars contains 10 cars, may-be less but not more (in reality, the Array class of the .NET Frameword provides a method used to expand an array). |
To use a collection as an entity, you can create a class for it. This class would be used to add items in the collection, to remove items in the list, or to perform other necessary operations. You can start a simple class as follows: class Collection { public Collection() { } } After creating the class for a collection, the collection becomes an object and its class can be used like any other. This means that, before using the collection, you can declare a variable for it. Here is an example: using System; class Collection { public Collection() { } } public class Exercise { static int Main(string[] args) { var list = new Collection(); return 0; } }
For an array-based list, because you must specify the number of items that the list will contain, you can declare an array as a field. Here is an example: class Collection { // This collection will be a list of decimal numbers private double[] Item = new double[20]; // Our default constructor, used to initialize the collection public Collection() { } } Although you can initialize an array in a C# class, remember that you can also use a constructor to initialize it. Here is an example: class Collection { public int MaxCount = 20; // This collection will be a list of decimal numbers private double[] Item; #region This section is used to set up the collection // Our default constructor, used to initialize the collection public Collection() { this.Item = new double[MaxCount]; } #endregion } A primary accessory you need when using a list is a count of the number of items in the list when/as they are added or deleted. This accessory is primarily a private field as a simple natural number. When the class is declared, this member variable should be set to 0 to indicate that the list is primarily empty: class Collection { public int MaxCount = 20; // This collection will be a list of decimal numbers private double[] Item; // This is the size of the collection private int size; #region This section is used to set up the collection // Our default constructor, used to initialize the collection public Collection() { this.Item = new double[MaxCount]; this.size = 0; } #endregion } Since the size field was declared private, if you plan to get the count of items in the list from outside the class, you should (must) provide a property to take care of this. This can simply be done as follows: using System; class Collection { public int MaxCount = 20; // This collection will be a list of decimal numbers private double[] Item; // This is the size of the collection private int size; #region This section is used to set up the collection // Our default constructor, used to initialize the collection public Collection() { this.Item = new double[MaxCount]; this.size = 0; } // This represents the number of items in the collection public int Count { get { return this.size; } } #endregion } public class Exercise { static int Main(string[] args) { var list = new Collection(); Console.WriteLine("Number of Items: {0}", list.Count); return 0; } } This would produce: Number of Items: 0 Press any key to continue . . .
Creating a collection consists of adding items to it. Items are usually added one at a time. The easiest way to do this is to add an item at the end of the existing collection. To add an item to the collection, because an array has (or is supposed to have) a fixed number of items, you should first check whether the list is already full. For an array-based list, the collection is full if its count of items is equal to the maximum number of items it can hold. If the collection can still receive at least one item, you can add the item at the end of the list and increase the count by one. Here is how this can be done: class Collection { public int MaxCount = 20; // This collection will be a list of decimal numbers private double[] Item; // This is the size of the collection private int size; #region This section is used to set up the collection // Our default constructor, used to initialize the collection public Collection() { this.Item = new double[MaxCount]; this.size = 0; } // This represents the number of items in the collection public int Count { get { return this.size; } } #endregion #region Operations on the collection // Adds a new item to the list if the list is not full // Increases the number of items in the list // Returns true if the item was added, otherwise returns false public bool Add(double item) { // Make sure the list is not yet full if (this.size < 20) { // Since the list is not full, add the item at the end this.Item[this.size] = item; // Increase the count and return the new position this.size++; // Indicate that the item was successfully added return true; } // If the item was not added, return false; return false; } #endregion } Once you have a means of adding items to the list, you can effectively create a list of items. Here is an example: public class Exercise { static int Main(string[] args) { var list = new Collection(); Console.WriteLine("Number of Items: {0}", list.Count); list.Add(224.52); list.Add(60.48); list.Add(1250.64); list.Add(8.86); list.Add(1005.36); Console.WriteLine("Number of Items: {0}", list.Count); return 0; } } This would produce: Number of Items: 0 Number of Items: 5 Press any key to continue . . .
After adding items to a collection, you can retrieve them to do what you intended the list for. To retrieve an item, you can locate it by its position, the same way you would do for an array. Having this index, you can check whether the position specified is negative or higher than the current count of items. If it is, there is nothing much to do since the index would be wrong. If the index is in the right range, you can retrieve its corresponding item. The method to do this can be implemented as follows: using System; class Collection { public int MaxCount = 20; // This collection will be a list of decimal numbers private double[] Item; // This is the size of the collection private int size; #region This section is used to set up the collection // Our default constructor, used to initialize the collection public Collection() { this.Item = new double[MaxCount]; this.size = 0; } // This represents the number of items in the collection public int Count { get { return this.size; } } #endregion #region Operations on the collection // Adds a new item to the list if the list is not full // Increases the number of items in the list // Returns true if the item was added, otherwise returns false public bool Add(double item) { // Make sure the list is not yet full if (size < MaxCount) { // Since the list is not full, add the "item" at the end this.Item[this.size] = item; // Increase the count and return the new position this.size++; // Indicate that the item was successfully added return true; } // If the item was not added, return false; return false; } // Retrieves an item from the list based on the specified index public double Retrieve(int pos) { // Make sure the index is in the range if (pos >= 0 && pos <= size) return this.Item[pos]; // If the index was wrong, return 0 return 0; } #endregion } public class Exercise { static int Main(string[] args) { var list = new Collection(); Console.WriteLine("Number of Items: {0}", list.Count); list.Add(224.52); list.Add(60.48); list.Add(1250.64); list.Add(8.86); list.Add(1005.36); for (int i = 0; i < list.Count; i++) Console.WriteLine("Item {0}: {1}\n", i + 1, list.Retrieve(i)); Console.WriteLine("Number of Items: {0}", list.Count); return 0; } } This would produce: Number of Items: 0 Item 1: 224.52 Item 2: 60.48 Item 3: 1250.64 Item 4: 8.86 Item 5: 1005.36 Number of Items: 5 Press any key to continue . . .
Inserting a new item in the collection allows you to add one
at a position of your choice. To insert an item in the list, you must provide
the new item and the desired position. Before performing this operation, you
must check two things. First, the list must not be empty because if it is, then
there is no way to insert an item (you insert something between two things, not
something between nothing). Second, the specified
position must be in the allowed range. using System; class Collection { public int MaxCount = 20; // This collection will be a list of decimal numbers private double[] Item; // This is the size of the collection private int size; #region This section is used to set up the collection // Our default constructor, used to initialize the collection public Collection() { this.Item = new double[MaxCount]; this.size = 0; } // This represents the number of items in the collection public int Count { get { return this.size; } } #endregion #region Operations on the collection // Adds a new item to the list if the list is not full // Increases the number of items in the list // Returns true if the item was added, otherwise returns false public bool Add(double item) { // Make sure the list is not yet full if (size < MaxCount) { // Since the list is not full, add the "item" at the end this.Item[this.size] = item; // Increase the count and return the new position this.size++; // Indicate that the item was successfully added return true; } // If the item was not added, return false; return false; } // Retrieves an item from the list based on the specified index public double Retrieve(int pos) { // Make sure the index is in the range if (pos >= 0 && pos <= size) return this.Item[pos]; // If the index was wrong, return 0 return 0; } // Before performing this operation, check that // 1. The list is not full // 2. The specified position is in an allowable range // Insert a new item at a specified position in the list. // After the new item is inserted, the count is increased public bool Insert(double itm, int pos) { // Check that the item can be added to the list if (size < 20 && pos >= 0 && pos <= size) { // Since there is room, // starting from the end of the list to the new position, // push each item to the next or up // to create room for the new item for (int i = size; i > pos - 1; i--) this.Item[i + 1] = this.Item[i]; // Now that we have room, put the new item in the position created this.Item[pos] = itm; // Since we have added a new item, increase the count this.size++; // Indicate that the operation was successful return true; } // Since the item could not be added, return false return false; } #endregion } public class Exercise { static int Main(string[] args) { var list = new Collection(); Console.WriteLine("Number of Items: {0}", list.Count); list.Add(224.52); list.Add(60.48); list.Add(1250.64); list.Add(8.86); list.Add(1005.36); for (var i = 0; i < list.Count; i++) Console.WriteLine("Item {0}: {1}", i + 1, list.Retrieve(i)); Console.WriteLine("Number of Items: {0}\n", list.Count); list.Insert(-707.16, 2); for (var i = 0; i < list.Count; i++) Console.WriteLine("Item {0}: {1}", i + 1, list.Retrieve(i)); Console.WriteLine("Number of Items: {0}\n", list.Count); return 0; } } This would produce: Number of Items: 0 Item 1: 224.52 Item 2: 60.48 Item 3: 1250.64 Item 4: 8.86 Item 5: 1005.36 Number of Items: 5 Item 1: 224.52 Item 2: 60.48 Item 3: -707.16 Item 4: 1250.64 Item 5: 8.86 Item 6: 1005.36 Number of Items: 6 Press any key to continue . . .
Another operation you can perform on a collection consists of deleting an item. This is also referred to as removing the item. To delete an item from the collection, you can provide its position. Before performing the operation, you can (should/must) first check that the specified position is valid. The method to perform this operation can be implemented as follows: using System; class Collection { public int MaxCount = 20; // This collection will be a list of decimal numbers private double[] Item; // This is the size of the collection private int size; #region This section is used to set up the collection // Our default constructor, used to initialize the collection public Collection() { this.Item = new double[MaxCount]; this.size = 0; } // This represents the number of items in the collection public int Count { get { return this.size; } } #endregion #region Operations on the collection // Adds a new item to the list if the list is not full // Increases the number of items in the list // Returns true if the item was added, otherwise returns false public bool Add(double item) { // Make sure the list is not yet full if (size < MaxCount) { // Since the list is not full, add the "item" at the end this.Item[this.size] = item; // Increase the count and return the new position this.size++; // Indicate that the item was successfully added return true; } // If the item was not added, return false; return false; } // Retrieves an item from the list based on the specified index public double Retrieve(int pos) { // Make sure the index is in the range if (pos >= 0 && pos <= size) return this.Item[pos]; // If the index was wrong, return 0 return 0; } // Before performing this operation, check that // 1. The list is not full // 2. The specified position is in an allowable range // Inserts a new item at a specified position in the list // After the new item is inserted, the count is increased public bool Insert(double itm, int pos) { // Check that the item can be added to the list if (size < 20 && pos >= 0 && pos <= size) { // Since there is room, // starting from the end of the list to the new position, // push each item to the next or up // to create room for the new item for (int i = size; i > pos - 1; i--) this.Item[i + 1] = this.Item[i]; // Now that we have room, put the new item in the position created this.Item[pos] = itm; // Since we have added a new item, increase the count this.size++; // Indicate that the operation was successful return true; } // Since the item could not be added, return false return false; } // Removes an item from the list // First check that the specified position is valid //-- Delete the item at that position and decrease the count --// public bool Delete(int pos) { // Make sure the position specified is in the range if (pos >= 0 && pos <= size) { // Since there is room, starting at the specified position, // Replace each item by the next for (int i = pos; i < this.size; i++) this.Item[i] = this.Item[i + 1]; // Since an item has been removed, decrease the count this.size--; // Indicate that the operation was successful return true; } // Since the position was out of range, return false return false; } #endregion } public class Exercise { static int Main(string[] args) { var list = new Collection(); Console.WriteLine("Number of Items: {0}", list.Count); list.Add(224.52); list.Add(60.48); list.Add(1250.64); list.Add(8.86); list.Add(1005.36); for (var i = 0; i < list.Count; i++) Console.WriteLine("Item {0}: {1}", i + 1, list.Retrieve(i)); Console.WriteLine("Number of Items: {0}\n", list.Count); list.Insert(-707.16, 2); list.Insert(-369952.274, 4); for (var i = 0; i < list.Count; i++) Console.WriteLine("Item {0}: {1}", i + 1, list.Retrieve(i)); Console.WriteLine("Number of Items: {0}\n", list.Count); list.Delete(5); list.Delete(3); for (var i = 0; i < list.Count; i++) Console.WriteLine("Item {0}: {1}", i + 1, list.Retrieve(i)); Console.WriteLine("Number of Items: {0}\n", list.Count); return 0; } } This would produce: Number of Items: 0 Item 1: 224.52 Item 2: 60.48 Item 3: 1250.64 Item 4: 8.86 Item 5: 1005.36 Number of Items: 5 Item 1: 224.52 Item 2: 60.48 Item 3: -707.16 Item 4: 1250.64 Item 5: -369952.274 Item 6: 8.86 Item 7: 1005.36 Number of Items: 7 Item 1: 224.52 Item 2: 60.48 Item 3: -707.16 Item 4: -369952.274 Item 5: 1005.36 Number of Items: 5 Press any key to continue . . . |
We have learned how to create an array as a list of items. Like an array, a collection is a series of items of the same type. The particularity with creating an array is that you must know in advance the number of items that will make up the list (in reality, in the .NET Framework, you just have to specify an initial count, such as 5; then, before adding a new item, you can check if there is room, if there is no room, you can provide room first, then add the new item). There are times when you don't know, you can't know, or you can't predict the number of items of the list. For this reason, you may want to create the list for which you don't specify the maximum number of items but you allow the user of the list to add, locate, or remove items at will. Before creating a list, you probably should first decide or define what the list would be made of. As different as collections are, one list can be made of numeric values, such as a list that will be made of numbers. You may want a list that is made of names. Such a list can be created from a class that includes a string member variable. Another type of list can contain complex objects.
After deciding what each item of the list would be made of, you can create a class that would manage the list. This class would be responsible for all operations that can be performed on the list. If the list will be made of primitive values, you can directly create a field of the desired type. Here is an example:
If the list will be made of objects, you can first create a class that specifies those types of items and then declare its variable in the list class. Here is an example of a simple class that holds a double-precision value: using System; public class Number { public double Item; } public class Numbers { Number Sample; } public class Exercise { static int Main(string[] args) { Numbers nbrs = new Numbers(); return 0; } } When creating a list, one of the aspects you should pay attention to is to keep track of the number of items in the list. To do this, you can create a property that holds the number. The value of this property would increase as the items are added to the list and the value would decrease as the items are removed from the list. Here is how this can be done: using System; public class Number { public double Item; } public class Numbers { int size; Number Sample; public Numbers() { size = 0; } public int Count { get { return size; } } } public class Exercise { static int Main(string[] args) { var nbrs = new Numbers(); Console.WriteLine("Number of Items: {0}", nbrs.Count); return 0; } } This would produce: Number of Items: 0 Press any key to continue . . .
A good collection is a list that can grow or shrink as the user wishes. When creating the list, you don't need to predict the maximum number of items that will be added to the list. When a list starts, it is empty or at least it must be considered like that, before any item is added to it. To specify this, you should declare a primary member variable. Although you can call it anything, it is usually called Head: The head member can be made private if you don't intend to access it outside of the class. If you want clients of the class to access it, you can make it public. Here is an example: public class Numbers { int listSize; Number Sample; public Numbers() { size = 0; Head = null; } public int Count { get { return listSize; } } public Number Head; }
We saw that when using an array, each member could be accessed using its index. If the items of a collection are not indexed, you must provide a mechanism to locate an item. To do this, you can use a starting point that determines the beginning of the list. Then, to locate an item, you can check whether another item follows that starting point:
If no item follows an item, either you are at the end of the list or the list is empty. To be able to scan a list from one item to another, you can declare a field. Although this member variable can be called anything, for the sake of clarify, you should call it Next. The field is the same type as its class. Here is an example: public class Number { public double Item; public Number Next; }
Since a list is fundamentally empty when it starts, the primary operation you can perform on a list is to add a new item to it. In order to indicate that you want to add an item to the list, you can create a method that receives an item as argument. For the return type, you have two main options. Because the main job of this method is to add a new item, which it hardly fails to do if you implement it right, it can be defined as void. Alternatively, you can make it return the position of the new item in the list. Here is an example: public class Numbers { int size; Number Sample; public Number Head; public Numbers() { size = 0; Head = null; } public int Count { get { return size; } } public int Add(Number NewItem) { Number Sample = new Number(); Sample = NewItem; Sample.Next = Head; Head = Sample; return size++; } }
Once a list exists, the user can explore it. One of the operations performed on a collection is to locate and retrieve an item. To do this, you can create a method that takes as argument an index. The method would examine the argument with regards to the number of items in the list to make sure the argument's value is in the range of the current items of the list. If the number is too low or too high, the method can return null or 0. If the number is in the range, the method can return the item at that position. Here is an example: public class Numbers { int size; Number Sample; public Number Head; public Numbers() { size = 0; Head = null; } public int Count { get { return size; } } public int Add(Number NewItem) { Number Sample = new Number(); Sample = NewItem; Sample.Next = Head; Head = Sample; return size++; } public Number Retrieve(int Position) { Number Current = Head; for (int i = Count - 1; i > Position && Current != null; i--) Current = Current.Next; return Current; } }
Deleting an item consists of removing it from the list. There are two main approaches you can use. You can simply ask the class to delete an item. In this case, it is usually the item at the end that gets deleted. If you do this, make sure you perform other routine operations such as decrementing the count of items in the list. Here is an example: public class Numbers { . . . No Change public bool Delete() { if (Head == null) { Console.WriteLine("The list is empty"); return false; } Number Current; Current = Head.Next; Head.Next = Current.Next; size--; return true; } } Another technique used to delete an item consists of specifying the position of the item to be deleted. To do this, you can pass an argument as the desired position. The method would check the range of values of the current list. If the specified position is beyond the appropriate range, the method can return false, 0, or null, depending on how you create it.
One of the operations hardly performed on a list is to find an item. This is because if you ask a list to locate a particular item, you must provide as much information as possible. Probably the most expedient way you can do this is to completely define an item and pass it to the list. Only if the (exact) item is found in the list would it be recognized. Here is an example: using System; public class Number { public double Item; public Number Next; } public class Numbers { int size; Number Sample; public Number Head; public Numbers() { size = 0; Head = null; } public int Count { get { return size; } } public int Add(Number NewItem) { Number Sample = new Number(); Sample = NewItem; Sample.Next = Head; Head = Sample; return size++; } public Number Retrieve(int Position) { Number Current = Head; for (int i = Count - 1; i > Position && Current != null; i--) Current = Current.Next; return Current; } public bool Delete() { if (Head == null) { Console.WriteLine("The list is empty"); return false; } Number Current; Current = Head.Next; Head.Next = Current.Next; size--; return true; } public bool Find(Number toFind) { Number Current = new Number(); if (toFind == null) return false; for (Current = Head; Current != null; Current = Current.Next) { if( Current.Item == toFind.Item ) return true; } return false; } } public class Exercise { static int Main(string[] args) { Number real; Numbers reals = new Numbers(); real = new Number(); real.Item = 2974.03; reals.Add(real); real = new Number(); real.Item = 748.25; reals.Add(real); real = new Number(); real.Item = 50883.82; reals.Add(real); real = new Number(); real.Item = 29.24; reals.Add(real); real = new Number(); real.Item = 772.85; reals.Add(real); real = new Number(); real.Item = 106628.06; reals.Add(real); Console.WriteLine("Number of items: {0}", reals.Count); for (int i = 0; i < reals.Count; i++) { Number nbr = reals.Retrieve(i); Console.WriteLine("Number[{0}] = {1}", i, nbr.Item); } reals.Delete(); Console.WriteLine("\nNumber of items: {0}", reals.Count); for (int i = 0; i < reals.Count; i++) { Number nbr = reals.Retrieve(i); Console.WriteLine("Number[{0}] = {1}", i, nbr.Item); } Number nbrToFind = new Number(); nbrToFind.Item = 26486.56; bool Found = reals.Find(nbrToFind); if (Found == true) Console.WriteLine("\nThe number {0} was found in the list", nbrToFind.Item); else Console.WriteLine("\nThe number {0} was NOT found in the list", nbrToFind.Item); nbrToFind = new Number(); nbrToFind.Item = 50883.82; Found = reals.Find(nbrToFind); if (Found == true) Console.WriteLine("The number {0} was found in the list\n", nbrToFind.Item); else Console.WriteLine("The number {0} was NOT found in the list\n", nbrToFind.Item); return 0; } } This would produce: Number of items: 6 Number[0] = 2974.03 Number[1] = 748.25 Number[2] = 50883.82 Number[3] = 29.24 Number[4] = 772.85 Number[5] = 106628.06 Number of items: 5 Number[0] = 2974.03 Number[1] = 748.25 Number[2] = 50883.82 Number[3] = 29.24 Number[4] = 106628.06 The number 26486.56 was NOT found in the list The number 50883.82 was found in the list Press any key to continue . . .
|
|
||
Previous | Copyright © 2008-2016, FunctionX, Inc. | Next |
|