The ArrayList Class

 

Introduction

To support the creation of any kind of list, the Microsoft .NET Framework provides the ArrayList class. The ArrayList class implements the ICollection interface. This class can be used to add, locate, or remove an item from a list. The class provides many other valuable operations routinely done on a list. Because of its flexibility, ArrayList is the most used class to create lists of items of any kind in a .NET application. Besides the ability to handle any type of list, ArrayList is a good class to study the theory of a collection. The routine operations found in the ArrayList class are the same found in many other collection-based classes you would use when creating commercial or graphical applications.

Besides the ability to create a collection, the ArrayList class has the built-in mechanism for serialization.

The ArrayList class is defined in the System::Collections namespace. Therefore, in order to use the ArrayList class in your application, you can first include the System::Collections namespace in the file that would perform ArrayList operations.

The Capacity of a List

After declaring an ArrayList variable, it is empty. As objects are added to it, the list grows. The list can grow tremendously as you wish. The number of items of the list is managed through the memory it occupies and this memory grows as needed. The number of items that the memory allocated is currently using is represented by the ArrayList::Capacity property. This will usually be the least of your concerns.

If for some reason, you want to intervene and control the number of items that your ArrayList list can contain, you can manipulate the Capacity property. For example, you can assign it a constant to set the maximum value that the list can contain. Once again, you will hardly have any reason to use the Capacity property: the compiler knows what to do with it.

If you set a fixed size on an ArrayList list, you may not be able to add a new item beyond the limit. In fact, if you attempt to do this, you may receive an error. A safe way is to check whether the list is fixed before performing a related operation. To find out whether a list is fixed, you can check the ArrayList variable's IsFixedSize property.

A Read-Only List

One of the reason for creating a list is to be able to add items to it, edit its items, retrieve an items, or delete items from it. These are the default operations. You can still limit these operations as you judge them unnecessary. For example, you may create a list and then initialize it with the items that you want the list to only have. If you don't intend to have the user adding items to it, you can create the list as read-only. To do this, you can call the ArrayList.ReadOnly() method. It is overloaded with two versions as follows:

public static ArrayList ReadOnly(ArrayList);
public static IList ReadOnly(IList);

This method is static. This means that you don't need to declare an instance of ArrayList to call them. Instead, to make the list read-only, call the ArrayList::ReadOnly() method and pass your ArrayList variable to it.

As we will see in the next sections, some operations cannot be performed on a read-only list. To perform such operations, you can first find out whether an ArrayList list is read-only. This is done by checking its IsReadOnly property.

Item Addition

The primary operation performed on a list is to create one. One of the biggest advantages of using a linked list is that you don't have to specify in advance the number of items of the list as done for an array. You can just start adding items. The ArrayList class makes this possible with the Add() method. Its syntax is:

public virtual int Add(object value);

The argument of this method is the value to add to the list. If the method succeeds with the addition, it returns the position where the value was added in the list. This is usually the last position in the list. If the method fails, the compiler would throw an error. One of the errors that could result from failure of this operation would be based on the fact that either a new item cannot be added to the list because the list is read-only, or the list was already full prior to adding the new item. Normally, a list can be full only if you had specified the maximum number of items it can contain using the ArrayList::Capacity property. As mentioned above, the list can be made read-only by passing its variable to the ArrayList::ReadOnly() method.

Practical Learning Practical Learning: Adding Items to an ArrayList List

  1. Change the Exercise.cpp file as follows:
     
    
                  
  2. Execute the application and continually create the following properties:
     
    
                  
  3. Close the DOS window

The Number of Items in the List

When using a list, at any time, you should be able to know the number of items that the list contains. This information is provided by the ArrayList::Count property. The Capacity and the Count have this in common: the value of each increases as the list grows and the same value decreases if the list shrinks. It is important to know that, although they look alike, there are various differences between the capacity of a list and the number of items it contains. Capacity is a read/write property. This means that, as we saw above, you can assign a value to the capacity to fix the number of items that the list can contain. You can also retrieve the value of the Capacity. The Count is read-only because it is used by the compiler to count the current number of items of the items and this counting is performed without your intervention.

Item Retrieval

Once a list is ready, you can perform different types of operations on it. Besides adding items, one of the most regular operations performed on a list consists of locating and retrieving its items. You have various options. To retrieve a single item based on its position, you can apply the square brackets of arrays to the variable. Like a normal array, an ArrayList list is zero-based. Another issue to keep in mind is that the ArrayList[] returns an Object value. Therefore, you may have to cast this value to your type of value to get it right.

Besides using the index to access an item from the list, ArrayList class implements the IEnumerable::GetEnumerator() method. For this reason, you can use the for each loop to access each member of the collection.

Practical Learning Practical Learning: Retrieving Items From an ArrayList List

  1. Change the Exercise.cpp file as follows:
  2. Execute the application and test it. Here is an example:
  3. Close the DOS window
  4. Execute the application again and test different options. Here are examples:
  5. Close the DOS window

Item Location

Instead of the square brackets that allow you to retrieve an item based on its position, you can look for an item based on its complete definition. You have various options. You can first "build" an item and ask the compiler to check whether any item in the list matches your definition. To perform this search, you can call the ArrayList.Contains() method. Its syntax is:

public virtual bool Contains(object item);

The item to look for is passed as argument to the method. The compiler would look for exactly the item, using its definition, in the list. If any detail of the argument fails to match any item of the ArrayList list, the method would return false. If all characteristics of the argument correspond to an item of the list, the method returns true.

Another option to look for an item in a list consists of calling the ArrayList::BinarySearch() method. It is overloaded in three versions and one of them uses the following syntax:

public virtual int BinarySearch(object value);

The item to look for is passed argument to the method.

Item Deletion

As opposed to adding an item to a list, you may want to remove one. To perform this operation, you have various options. You can ask the compiler to look for an item in the list and if, or once, the compile finds it, it would delete the item. To perform this type of deletion, you can call the ArrayList.Remove() method. Its syntax is:

public virtual void Remove(object obj);

This method accepts as argument the item that you want to delete from the list. To perform this operation, the list must not be read-only.

The Remove() method allows you to specify the exact item you want to delete from a list. Another option you have consists of deleting an item based on its position. This is done using the RemoveAt() method whose syntax is:

public virtual void RemoveAt(int index);

With this method, the position of the item is passed as argument. If the position is not valid because either it is lower or higher than the current Count, the compiler would throw an ArgumentOutOfRangeException exception.

To remove all items from a list at once, you can call the ArrayList::Clear() method. Its syntax is:

public virtual void Clear();

Hash Tables

 

Introduction

If you have been playing a little deeper with Microsoft Windows for a while, you are probably familiar with objects referred to as initialization files or ini files. These are files whose contents are made of lines that each displays a combination of a right value assigned to a left value. Here is an example:

PROJECT=AIOCPE
MANUFACTURER=HP
Wrapper=1
DEFAULT=1
LOG_DISABLED=0
LOG_ERROR=1
LOG_WARNING=2
LOG_MAINTRACE=4
LOG_DETAILEDTRACE=8
FILESIZE=524288

A hash table is list of items that each (item) is made of a right object assigned to a left object. The object on the left side is called a key. The object on the right side is called a value. Based on this, an item of a hash table is in the form:

Key=Value

Most hash tables are made of string keys and String ^ Values but the key or the value can also be a number or a more complex item. There is no strict rule as to what you use a hash table for. When you create one, it is up to you to decide what you want to do with it.

Practical LearningPractical Learning: Introducing Hash Tables

  1. Create a new Console Application named GeorgetownCleaningServices8
  2. To save the project, on the Standard toolbar, click the Save All button
  3. Accept all the defaults and click Save
  4. To create a new class, on the main menu, click Project -> Add Class...
  5. Set the Name to CCleaningOrderDetails and click Add
  6. Change the file as follows:
    using namespace System;
    
    [Serializable]
    public ref class CCleaningOrderDetails
    {
    public:
        // Receipt identification
        int ReceiptNumber;
        String ^ CustomerName;
        String ^ CustomerPhoneNumber;
        // The date the cleaning items were deposited
        DateTime OrderDate;
        DateTime OrderTime;
        // Numbers to represent cleaning items
        unsigned int NumberOfShirts;
        unsigned int NumberOfPants;
        unsigned int NumberOtherItems;
    
        // Price of items
        double PriceOneShirt = 0.95;
        double PriceAPairOfPants = 2.95;
        double PriceOtherItems = 4.55;
        double TaxRate = 0.0575;  // 5.75%
    
        // Each of these sub totals will be used for cleaning items
        double SubTotalShirts;
        double SubTotalPants;
        double SubTotalOtherItems;
    
        // Values used to process an order
        double TotalOrder;
        double TaxAmount;
        double SalesTotal;
    
        CCleaningOrderDetails();
    };
  7. Save the file

Creating a Hash Table

The .NET Framework supports hash tables at different levels but probably the most common class used is called Hashtable. The Hashtable class implements the ISerializable interface (that makes it possible for the list to be serialized(, the ICollection interface (used to keep track of the number of items in the list), and the IEnumerable interface (that would allow you to use the foreach loop).

Before using a hash table, you can declare a variable of type Hashtable using one of its constructors such as the default one. Here is an example:

using namespace System;
using namespace System::Collections;

int main()
{
    Hashtable ^ Chelsea20062007 = gcnew Hashtable;

    return 0;
}

In this case, the primary list would be empty.

To add an item to the list, you can call the Add() method. Its syntax is:

public:
    virtual void Add(Object ^ Key, Object ^ Value);

As you can see, you must provide the key and the value as the first and second arguments to the method. Here are examples of calling the Add() method:

using namespace System;
using namespace System::Collections;

int main()
{
    Hashtable ^ Chelsea20062007 = gcnew Hashtable;

    Chelsea20062007->Add(L"Michael", L"Ballack");
    Chelsea20062007->Add(L"Didier", L"Drogba");

    return 0;
}

When calling the Add() method, you must provide a valid Key argument: it cannot be null. For example, the following code would produce an error:

using namespace System;
using namespace System::Collections;

int main()
{
    Hashtable ^ Chelsea20062007 = gcnew Hashtable;

    Chelsea20062007->Add(L"Michael", L"Ballack");
    Chelsea20062007->Add(L"Didier", L"Drogba");
    Chelsea20062007->Add(nullptr, L"Essien");

    return 0;
}

This would produce:

Unhandled Exception: System.ArgumentNullException:
 Key cannot be null.

When adding the items to the list, each key must be unique: you cannot have two exact keys. If you try adding a key that exists already in the list, the compiler would throw an ArgumentException exception. Based on this, the following code would not work because, on the third call, a "Michael" key exists already:

using namespace System;
using namespace System::Collections;

int main()
{
    Hashtable ^ Chelsea20062007 = gcnew Hashtable;

    Chelsea20062007->Add(L"Michael", L"Ballack");
    Chelsea20062007->Add(L"Didier",  "Drogba");
    Chelsea20062007->Add(L"Michael", L"Essien");

    return 0;
}

This would produce:

Unhandled Exception: System.ArgumentException: 
Item has already been added. Key
in dictionary: 'Michael'  Key being added: 'Michael'

Besides the Add() method, you can use the indexed property of the Hashtable class to add an item to the list. To do this, enter the Key in the square brackets of the property and assign it the desired Value. Here is an example:

using namespace System;
using namespace System::Collections;

int main()
{
    Hashtable ^ Chelsea20062007 = gcnew Hashtable;

    Chelsea20062007->Add(L"Michael", L"Ballack");
    Chelsea20062007->Add(L"Didier", L"Drogba");

    Chelsea20062007[L"Claude"] = L"Makelele";

    return 0;
}

After adding one or more items to the list, they are stored in two collections. The keys are stored in a collection represented by a property named Keys. The values are stored in the Values property. Each of these properties is of type ICollection.

Accessing the Items of a Hash Table

Although, or because, the key and value are distinct, to consider their combination as a single object, the .NET Framework provides the DictionaryEntry structure. To access an item, you can use the foreach loop to visit each item. To support the foreach loop, the Hashtable class implements the IEnumerable.GetEnumerator() method. In this case, the item is of type DictionaryEntry: it contains a Key and a Value in combination. The DictionaryEntry structure contains two properties named Key and Value to identify the components of a combination. Here is an example:

using namespace System;
using namespace System::Collections;

int main()
{
    Hashtable ^ Chelsea20062007 = gcnew Hashtable;

    Chelsea20062007->Add(L"Michael", L"Ballack");
    Chelsea20062007->Add(L"Didier", L"Drogba");
    Chelsea20062007[L"Claude"] = L"Makelele";

    for each(DictionaryEntry ^ entry in Chelsea20062007)
        Console::WriteLine(L"{0} {1}", entry->Key, entry->Value);

    Console::WriteLine();
    return 0;
}

This would produce:

Didier Drogba
Michael Ballack
Claude Makelele

Press any key to continue . . .

Practical LearningPractical Learning: Using a Hash Table

  1. To create a new class, in the Class View, right-click GeorgetownCleaningServices8 -> Add -> Class...
  2. Set the Name to Customers and press Enter
  3. Change the file as follows:
    using namespace System;
    {
        [Serializable]
        public ref class Customer
        {
            public String ^ Name;
            public String ^ PhoneNumber;
        }
    }
  4. To create a new class, in the Solution Explorer, right-click GeorgetownCleaningServices8 -> Add -> Class...
  5. Set the Name to CleaningOrderManagement and click Add
  6. Change the file as follows:
    using namespace System;
    using namespace System::IO;
    using namespace System::Collections;
    using namespace System::Runtime::Serialization::Formatters::Binary;
    
    
    {
        public ref class CCleaningDeposit
        {
            // We need a global customer info to 
            // modify/update it from anywhere
            String ^ strCustomerName;
            String ^ strPhoneNumber;
    
            // This is the list that will hold the cleaning orders
            ArrayList CleaningOrders;
            // This is a list that will hold the combinations of 
            // a customer's name and telephone number
            private Hashtable Customers;
            public CCleaningOrderDetails depot;
    
            public CCleaningDeposit()
            {
                this->Customers = gcnew Hashtable();
                this->CleaningOrders = gcnew ArrayList();
                this->strPhoneNumber = L"(000) 000-0000";
                this->strCustomerName = L"Unknown";
                this->depot = gcnew CCleaningOrderDetails();
    
                CheckDefaultFolder();
                CheckDefaultFiles();
            }
    
            private void CheckDefaultFolder()
            {
                DirectoryInfo diGCS =
                    new DirectoryInfo("C:\Georgetown " 
                                      "Cleaning Services");
                try
                {
                    if (!diGCS.Exists)
                        diGCS.Create();
                }
                catch (IOException)
                {
                    Console::WriteLine(L"The directory could not be created");
                }
            }
    
            // This method ensures that there are the necessary files 
            // used to process a cleaning order
            public void CheckDefaultFiles()
            {
                FileStream fsCustomers = nullptr;
                BinaryFormatter bfCustomers = gcnew BinaryFormatter();
    
                // The Customers.cst file will contain the 
                // information about the customers
                String ^ strFilename =
                    "C:\Georgetown Cleaning Services\Customers.cst";
    
                // When the application starts, if the list of
                // customers doesn't (yet) exist, then create it
                if (!File.Exists(strFilename))
                {
                    Customers->Add(strPhoneNumber, strCustomerName);
    
                    try
                    {
                        fsCustomers  = gcnew FileStream(strFilename,
                                                      FileMode::Create,
                                                      FileAccess::Write);
                        bfCustomers->Serialize(fsCustomers, Customers);
                    }
                    finally
                    {
                        fsCustomers->Close();
                    }
                }
                
                // The CleaningOrders.gco file will 
                // contain the cleaning orders
                strFilename = "C:\Georgetown Cleaning " 
                              "Services\CleaningOrders.gco";
    
                if (!File.Exists(strFilename))
                {
                    FileStream fsCleaningOrders = nullptr;
                    BinaryFormatter bfCleaningOrders =
                        new BinaryFormatter();
    
                    // This file will contain only useless default values
                    // Normally, this cleaning order should never be deleted
                    depot->ReceiptNumber = 0;
                    depot->CustomerName = strCustomerName;
                    depot->CustomerPhoneNumber = strPhoneNumber;
                    depot->OrderDate = gcnew DateTime(1960, 1, 1);
                    depot->OrderTime = gcnew DateTime(1960, 1, 1,
                                                        1, 1, 1);
                    depot->NumberOfShirts = 0;
                    depot->NumberOfPants = 0;
                    depot->NumberOtherItems = 0;
    
                    depot->PriceOneShirt = 0.00M;
                    depot->PriceAPairOfPants = 0.00M;
                    depot->PriceOtherItems = 0.00M;
                    depot->TaxRate = 0.00M;  // 5.75%
    
                    depot->SubTotalShirts = 0;
                    depot->SubTotalPants = 0;
                    depot->SubTotalOtherItems = 0;
    
                    depot->TotalOrder = 0;
                    depot->TaxAmount = 0;
                    depot->SalesTotal = 0;
    
                    // After creating this default order, 
                    // add it to the collection
                    this->CleaningOrders->Add(this->depot);
    
                    // After creating the cleaning order, save it
                    try
                    {
                        fsCleaningOrders = gcnew FileStream(strFilename,
                                                          FileMode::Create,
                                                          FileAccess::Write);
                        bfCleaningOrders->Serialize(fsCleaningOrders,
                                                   CleaningOrders);
                    }
                    finally
                    {
                        fsCleaningOrders->Close();
                    }
                }
            }
    
            // This method is used to find out if the customer 
            // already exists in our database
            private void IdentifyCustomer()
            {
                bool found = false;
                String ^ strTelephoneNumber = L"000";
    
                do
                {
                    Console::Write(L"Enter Customer Phone Number: ");
                    strTelephoneNumber = Console::ReadLine();
    
                    // Remove the spaces, parentheses, and dashes, if any
                    strTelephoneNumber =
                        strTelephoneNumber.Replace(L" ", L"");
                    strTelephoneNumber =
                        strTelephoneNumber.Replace(L"(L", L"");
                    strTelephoneNumber =
                        strTelephoneNumber.Replace(L")", L"");
                    strTelephoneNumber =
                        strTelephoneNumber.Replace(L"-", L"");
    
                    if (strTelephoneNumber.Length != 10)
                    {
                        // We will use a (small version of) 
                        // Canada and US telephone numbers
                        Console::WriteLine(L"Invalid telphone number: " 
                                          "you entered {0} " 
                                          "characters instead of 10 digits",
                                          strTelephoneNumber.Length);
                    }
                } while (strTelephoneNumber.Length != 10);
    
                // We will use the same formula for 
                // telephone numbers: (000) 000-0000
                strPhoneNumber = L"(L"  strTelephoneNumber.Substring(0, 3) +
                                    ") "  strTelephoneNumber.Substring(3, 3) +
                                    "-"  strTelephoneNumber.Substring(6, 4);
    
                String ^ strFilename =
                    "C:\Georgetown Cleaning Services\Customers.cst";
    
                if (File.Exists(strFilename))
                {
                    FileStream fsCustomers = File.Open(strFilename,
                                                       FileMode::Open,
                                                       FileAccess::Read);
                    BinaryFormatter bfCustomers = gcnew BinaryFormatter();
                    Customers = (Hashtable)bfCustomers.Deserialize(fsCustomers);
                    fsCustomers->Close();
    
                    for each(DictionaryEntry de in Customers)
                    {
                        if ((string)de.Key == strPhoneNumber)
                        {
                            found = true;
                            strPhoneNumber = (string)de.Key;
                            strCustomerName = (string)de.Value;
                        }
                    }
    
                    if (found == true)
                    {
                        Console::WriteLine(L"\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-");
                        Console::WriteLine(L"-/- Georgetown Cleaning Services -/-");
                        Console::WriteLine(L"------------------------------------");
                        Console::WriteLine(L"Customer Name: {0}", strCustomerName);
                        Console::WriteLine(L"Phone Number:  {0}", strPhoneNumber);
                        Console::WriteLine(L"------------------------------------\n");
                    }
                    else // If the customer information was not found in a file
                    {
                        Console::WriteLine(L"This is the first cleaning order "  
                                          "of this customer");
                        FileStream fsCustomer = gcnew FileStream(strFilename,
    							   FileMode::Create,
    							   FileAccess::Write);
                        BinaryFormatter bfCustomer = gcnew BinaryFormatter();
                        Console::Write(L"Enter Customer Name: ");
                        strCustomerName = Console::ReadLine();
    
                        Customers->Add(strPhoneNumber, strCustomerName);
                        bfCustomer->Serialize(fsCustomer, Customers);
                        fsCustomer->Close();
                    }
                }
                else
                    Console::WriteLine(L"The Customers list was not found");
            }
    
            public void ProcessOrder()
            {
                // These two pieces of information are used for money change
                double AmountTended;
                double Difference;
    
                Console::WriteLine(L"-/- Georgetown Cleaning Services -/-");
                this->IdentifyCustomer();
                
                try
                {
                    Console::Write(L"Enter the order date(mm/dd/yyyy):  ");
                    depot->OrderDate = DateTime::Parse(Console::ReadLine());
                }
                catch (FormatException)
                {
                    Console::WriteLine(L"The value you entered is not a valid date");
                }
                try
                {
                    Console::Write(L"Enter the order time(hh:mm AM/PM): ");
                    depot->OrderTime = DateTime::Parse(Console::ReadLine());
                }
                catch
                {
                    Console::WriteLine(L"The value you entered is not a valid time");
                }
    
                // Request the quantity of each category of items
                try
                {
                    Console::Write(L"Number of Shirts:      ");
                    depot->NumberOfShirts =
                        unsigned int::Parse(Console::ReadLine());
                    if (depot->NumberOfShirts < unsigned int.MinValue)
                        throw new OverflowException(L"Negative value not " 
                                                    "allowed for shirts");
                }
                catch (FormatException)
                {
                    Console::WriteLine(L"The value you typed for the number of " 
                                      "shirts is not a valid number");
                }
                try
                {
                    Console::Write(L"Number of Pants:       ");
                    depot->NumberOfPants =
                        unsigned int::Parse(Console::ReadLine());
                }
                catch (FormatException)
                {
                    Console::WriteLine(L"The value you typed for the number of " 
                                      "pair or pants is not a valid number");
                }
                try
                {
                    Console::Write(L"Number of Other Items: ");
                    depot->NumberOtherItems = unsigned int::Parse(Console::ReadLine());
                }
                catch (FormatException)
                {
                    Console::WriteLine(L"The value you typed for the number of " 
                                      "other items is not a valid number");
                }
                // Perform the necessary calculations
                depot->SubTotalShirts =
                    depot->NumberOfShirts * depot->PriceOneShirt;
                depot->SubTotalPants =
                    depot->NumberOfPants * depot->PriceAPairOfPants;
                depot->SubTotalOtherItems =
                    depot->NumberOtherItems * depot->PriceOtherItems;
                // Calculate the "temporary" total of the order
                depot->TotalOrder = depot->SubTotalShirts +
                                        depot->SubTotalPants +
                                        depot->SubTotalOtherItems;
    
                // Calculate the tax amount using a constant rate
                depot->TaxAmount = depot->TotalOrder * depot->TaxRate;
                // Add the tax amount to the total order
                depot->SalesTotal = depot->TotalOrder + depot->TaxAmount;
    
                // Communicate the total to the user...
                Console::WriteLine(L"\nThe Total order is: {0:C}", depot->SalesTotal);
                // and request money for the order
                try
                {
                    Console::Write(L"Amount Tended? ");
                    AmountTended = double::Parse(Console::ReadLine());
                }
                catch (FormatException)
                {
                    Console::WriteLine(L"You were asked to enter an " 
                                      "amount of money but...");
                }
                // Calculate the difference owed to the customer
                // or that the customer still owes to the store
                Difference = AmountTended - depot->SalesTotal;
    
                this->PreviewReceipt();
                this->SaveCleaningOrder();
            }
    
            public void PreviewReceipt()
            {
                Console::WriteLine();
                // Display the receipt
                Console::WriteLine(L"====================================");
                Console::WriteLine(L"-/- Georgetown Cleaning Services -/-");
                Console::WriteLine(L"====================================");
                Console::WriteLine(L"Customer:    {0}", this->strCustomerName);
                Console::WriteLine(L"Home Phone:  {0}", this->strPhoneNumber);
                Console::WriteLine(L"Order Date:  {0:D}", depot->OrderDate);
                Console::WriteLine(L"Order Time:  {0:t}", depot->OrderTime);
                Console::WriteLine(L"------------------------------------");
                Console::WriteLine(L"Item Type    Qty Unit/Price Sub-Total");
                Console::WriteLine(L"------------------------------------");
                Console::WriteLine(L"Shirts      {0,3}   {1,4}      {2,6}",
                                  depot->NumberOfShirts,
                                  depot->PriceOneShirt,
                                  depot->SubTotalShirts);
                Console::WriteLine(L"Pants       {0,3}   {1,4}      {2,6}",
                                 depot->NumberOfPants,
                                 depot->PriceAPairOfPants,
                                 depot->SubTotalPants);
                Console::WriteLine(L"Other Items {0,3}   {1,4}      {2,6}",
                                  depot->NumberOtherItems,
                                  depot->PriceOtherItems,
                                  depot->SubTotalOtherItems);
                Console::WriteLine(L"------------------------------------");
                Console::WriteLine(L"Total Order:   {0,6}",
                                  depot->TotalOrder.ToString(L"C"));
                Console::WriteLine(L"Tax Rate:      {0,6}",
                                  depot->TaxRate.ToString(L"P"));
                Console::WriteLine(L"Tax Amount:    {0,6}",
                                  depot->TaxAmount.ToString(L"C"));
                Console::WriteLine(L"Net Price:     {0,6}",
                                  depot->SalesTotal.ToString(L"C"));
                Console::WriteLine(L"------------------------------------");
                Console::WriteLine(L"Amount Tended: {0,6}",
                                  AmountTended.ToString(L"C"));
                Console::WriteLine(L"Difference:    {0,6}",
                                  Difference.ToString(L"C"));
                Console::WriteLine(L"====================================");
            }
    
            public void SaveCleaningOrder()
            {
                int highReceiptNumber = 0;
                FileStream fsCleaningOrders = nullptr;
                BinaryFormatter bfCleaningOrders = gcnew BinaryFormatter();
    
                String ^ strFilename =
                    "C:\Georgetown Cleaning Services\CleaningOrders.gco";
    
                if (File.Exists(strFilename))
                {
                    try
                    {
                        fsCleaningOrders = gcnew FileStream(strFilename,
                                                          FileMode::Open,
                                                          FileAccess::Read);
                        CleaningOrders =
                            (ArrayList)bfCleaningOrders.Deserialize(fsCleaningOrders);
                    }
                    finally
                    {
                        fsCleaningOrders->Close();
                    }
    
                    highReceiptNumber =
                        ((CCleaningOrderDetails)CleaningOrders[CleaningOrders.Count
                                                              - 1]).ReceiptNumber;
    
                    depot->ReceiptNumber = highReceiptNumber + 1;
                    depot->CustomerName = strCustomerName;
                    depot->CustomerPhoneNumber = strPhoneNumber;
    
                    this->CleaningOrders->Add(this->depot);
    
                    try
                    {
                        fsCleaningOrders = gcnew FileStream(strFilename,
                                                          FileMode::Create,
                                                          FileAccess::Write);
                        bfCleaningOrders->Serialize(fsCleaningOrders,
                                                   CleaningOrders);
                    }
                    finally
                    {
                        fsCleaningOrders->Close();
                    }
                }
                else
                    Console::WriteLine(L"The cleaning orders could " 
                                      "not be retrieved");
            }
    
            public void OpenCleaningOrder()
            {
                bool foundReceipt = false;
    
                try
                {
                    Console::Write(L"Enter Receipt Number: ");
                    int recNumber = int::Parse(Console::ReadLine());
    
                    FileStream fsCleaningOrders = nullptr;
                    BinaryFormatter bfCleaningOrders = gcnew BinaryFormatter();
    
                    String ^ strFilename =
                        "C:\Georgetown Cleaning Services\CleaningOrders.gco";
    
                    if (File.Exists(strFilename))
                    {
                        try
                        {
                            fsCleaningOrders = gcnew FileStream(strFilename,
                                                              FileMode::Open,
                                                              FileAccess::Read);
                            CleaningOrders =
                                (ArrayList)bfCleaningOrders.Deserialize(fsCleaningOrders);
                        }
                        finally
                        {
                            fsCleaningOrders->Close();
                        }
    
                        for each(CCleaningOrderDetails cod in CleaningOrders)
                        {
                            if (cod.ReceiptNumber == recNumber)
                            {
                                foundReceipt = true;
    
                                // Display the
                                Console::WriteLine(L"====================================");
                                Console::WriteLine(L"-/- Georgetown Cleaning Services -/-");
                                Console::WriteLine(L"====================================");
                                Console::WriteLine(L"Receipt #:   {0}", cod.ReceiptNumber);
                                Console::WriteLine(L"Customer:    {0}", cod.CustomerName);
                                Console::WriteLine(L"Home Phone:  {0}",
    					      cod.CustomerPhoneNumber);
                                Console::WriteLine(L"Order Date:  {0:D}", cod.OrderDate);
                                Console::WriteLine(L"Order Time:  {0:t}", cod.OrderTime);
                                Console::WriteLine(L"------------------------------------");
                                Console::WriteLine(L"Item Type   Qty Unit/Price Sub-Total");
                                Console::WriteLine(L"------------------------------------");
                                Console::WriteLine(L"Shirts      {0,3}   {1,4}      {2,6}",
                                                  cod.NumberOfShirts,
                                                  cod.PriceOneShirt,
                                                  cod.SubTotalShirts);
                                Console::WriteLine(L"Pants       {0,3}   {1,4}      {2,6}",
                                                 cod.NumberOfPants,
                                                 cod.PriceAPairOfPants,
                                                 cod.SubTotalPants);
                                Console::WriteLine(L"Other Items {0,3}   {1,4}      {2,6}",
                                                  cod.NumberOtherItems,
                                                  cod.PriceOtherItems,
                                                  cod.SubTotalOtherItems);
                                Console::WriteLine(L"------------------------------------");
                                Console::WriteLine(L"Total Order:   {0,6}",
                                                  cod.TotalOrder.ToString(L"C"));
                                Console::WriteLine(L"Tax Rate:      {0,6}",
                                                  cod.TaxRate.ToString(L"P"));
                                Console::WriteLine(L"Tax Amount:    {0,6}",
                                                  cod.TaxAmount.ToString(L"C"));
                                Console::WriteLine(L"Net Price:     {0,6}",
                                                  cod.SalesTotal.ToString(L"C"));
                                Console::WriteLine(L"====================================");
    
                                return;
                            } // if found receipt number
                        }// foreach
    
                        if (foundReceipt == false)
                            Console::WriteLine(L"No cleaning order with that " 
                                              "receipt number was found");
                    }// if file exists
                    else
                        Console::WriteLine(L"The cleaning orders were not found");
                }
                catch (FormatException)
                {
                    Console::WriteLine(L"Invalid Choice");
                }
            }
        }
    }
  7. Access the Program.cs file and change it as follows:
    using namespace System;
    
    namespace GeorgetownCleaningServicesHatch1
    {
        {
            int main()
            {
                char answer = 'q';
                CCleaningDeposit depotOrder = gcnew CCleaningDeposit();
    
                do
                {
                    Console::WriteLine(L"================================================");
                    Console::WriteLine(L"Georgetown Cleaning Services");
                    Console::WriteLine(L"================================================");
                    try
                    {
                        Console::WriteLine(L"What do you want to do?");
                        Console::WriteLine(L"1. Process a new cleaning order");
                        Console::WriteLine(L"2. Retrieve an existing order");
                        Console::WriteLine(L"0. Quit");
                        Console::Write(L"Your Choice: ");
                        answer = char::Parse(Console::ReadLine());
                    }
                    catch (FormatException)
                    {
                        Console::WriteLine(L"Invalid Answer");
                    }
    
                    switch (answer)
                    {
                        case '1':
                            depotOrder.ProcessOrder();
                            break;
    
                        case '2':
                            depotOrder.OpenCleaningOrder();
                            break;
    
                        default:
                            break;
                    }
                } while ((answer == '1') ||
                        (answer == '2'));
                Console::WriteLine();
                return 0;
            }
        }
    }
  8. Execute the application to test it
  9. First create a few customers
  10. Then process a few orders:
  11. The open a previously created order 
  12. Close the DOS window

Locating an Item in a Hash Table

Locating an item in a hash table consists of looking for either a key, a value, or a combination of Key=Value. The Hashtable class is equipped to handle these operations with little effort on your part. If you know the key of an item but want to find a value, you can use the index property because it produces it. Here is an example:

using namespace System;
using namespace System::Collections;
{  
    {
        int main()
        {
            Hashtable ^ Chelsea20062007 = gcnew Hashtable;

            Chelsea20062007->Add(L"Michael", L"Ballack");
            Chelsea20062007->Add(L"Didier", L"Drogba");
            Chelsea20062007[L"Claude"] = L"Makelele";

            String ^ Value = (string)Chelsea20062007[L"Didier"];
            Console::WriteLine(L"The value of the Didier key is {0}",
                              Value);

            Console::WriteLine();
            return 0;
        }
    }
}

This would produce:

The value of the Didier key is Drogba

Press any key to continue . . .

To find out whether a Key=Value item exists in the list, you can call the Contains() method. Its syntax is:

public virtual bool Contains(object key);

To look for an item, you pass its key as argument to this method. Here is an example:

using namespace System;
using namespace System::Collections;


{
    
    {
        int main()
        {
            Hashtable ^ Chelsea20062007 = gcnew Hashtable;

            Chelsea20062007->Add(L"Michael", L"Ballack");
            Chelsea20062007->Add(L"Didier", L"Drogba");
            Chelsea20062007[L"Claude"] = L"Makelele";

            Console::WriteLine(L"List of items");
            for each(DictionaryEntry ^ entry in Chelsea20062007)
                Console::WriteLine(L"{0} {1}", entry->Key, entry->Value);

            bool found = Chelsea20062007->Contains(L"Claude");

            if (found == true)
                Console::WriteLine(L"\nThe list contains an item " 
                                  "whose key is Claude");
            else
                Console::WriteLine(L"\nThe list doesn't contain an " 
                                  "item whose key is Claude");

            found = Chelsea20062007->Contains(L"James");

            if (found == true)
                Console::WriteLine(L"\nThe list contains an item " 
                                  "whose key is Claude");
            else
                Console::WriteLine(L"\nThe list doesn't contain an " 
                                  "item whose key is James");

            Console::WriteLine();
            return 0;
        }
    }
}

This would produce:

List of items
Didier Drogba
Michael Ballack
Claude Makelele

The list contains an item whose key is Claude

The list doesn't contain an item whose key is James

Press any key to continue . . .

To find out whether a particular key exists in the list, you can call the ContainsKey() method whose syntax is:

public virtual bool ContainsKey(object key);

To find out whether a particular key exists in the list, you can call the ContainsKey() method whose syntax is:

public virtual bool ContainsValue(object key);

When calling this method, pass a Value value as argument. Here is an example:

using namespace System;
using namespace System::Collections;


{
    
    {
        int main()
        {
            Hashtable ^ Chelsea20062007 = gcnew Hashtable;

            Chelsea20062007->Add(L"Michael", L"Ballack");
            Chelsea20062007->Add(L"Didier", L"Drogba");
            Chelsea20062007[L"Claude"] = L"Makelele";

            Console::WriteLine(L"List of items");
            for each(DictionaryEntry ^ entry in Chelsea20062007)
                Console::WriteLine(L"{0} {1}", entry->Key, entry->Value);

            bool found = Chelsea20062007->ContainsValue(L"Makelele");

            if (found == true)
                Console::WriteLine(L"\nMakelele plays for Chelsea");
            else
                Console::WriteLine(L"\nMakelele doesn't plays for Chelsea");

            found = Chelsea20062007->ContainsValue(L"Fortune");

            if (found == true)
                Console::WriteLine(L"\nRonaldinho plays for Chelsea");
            else
                Console::WriteLine(L"\nRonaldinho doesn't plays for Chelsea");

            Console::WriteLine();
            return 0;
        }
    }
}

This would produce:

List of items
Didier Drogba
Michael Ballack
Claude Makelele

Makele plays for Chelsea

Ronaldinho doesn't plays for Chelsea

Press any key to continue . . .

Removing Items From a Hash Table

To delete one item from the list, you can call the Remove() method. Its syntax is:

public virtual void Remove(object key);

Here is an example:

using namespace System;
using namespace System::Collections;

int main()
{
    Hashtable ^ Chelsea20062007 = gcnew Hashtable;

    Chelsea20062007->Add(L"Michael", L"Ballack");
    Chelsea20062007->Add(L"Didier", L"Drogba");
    Chelsea20062007[L"Claude"] = L"Makelele";

    Console::WriteLine(L"List of items");
    for each(DictionaryEntry ^ entry in Chelsea20062007)
        Console::WriteLine(L"{0} {1}", entry->Key, entry->Value);

    Chelsea20062007->Remove(L"Didier");
    Console::WriteLine(L"\nThe item that contains " 
                       L"Didier has been removed\n");

    Console::WriteLine(L"List of items");
    for each(DictionaryEntry ^ entry in Chelsea20062007)
                Console::WriteLine(L"{0} {1}", entry->Key, entry->Value);

            Console::WriteLine();
            return 0;
        }
    }
}

This would produce:

List of items
Didier Drogba
Michael Ballack
Claude Makelele

The item that contains Didier has been removed

List of items
Michael Ballack
Claude Makelele

Press any key to continue . . .

To delete all items from the list, you can call the Clear() method. Its syntax is:

public virtual void Clear();

This is an example:

using namespace System;
using namespace System::Collections;

int main()
{
    Hashtable ^ Chelsea20062007 = gcnew Hashtable;

    Chelsea20062007->Add(L"Michael", L"Ballack");
    Chelsea20062007->Add(L"Didier", L"Drogba");
    Chelsea20062007[L"Claude"] = L"Makelele";

    Console::WriteLine(L"List of items");
    for each(DictionaryEntry ^ entry in Chelsea20062007)
        Console::WriteLine(L"{0} {1}", entry->Key, entry->Value);

    Chelsea20062007->Clear();
    Console::WriteLine(L"\nThe list is now empty!");

    Console::WriteLine(L"List of items");
    for each(DictionaryEntry ^ entry in Chelsea20062007)
                Console::WriteLine(L"{0} {1}", entry->Key, entry->Value);

            Console::WriteLine();
            return 0;
        }
    }
}

This would produce:

List of items
Didier Drogba
Michael Ballack
Claude Makelele

The list is now empty!
List of items

Press any key to continue . . .

Stacks

 

Introduction

A stack is a technique of creating a list so that the last item added to the list is also the first one that can be removed. It can be illustrated as placing a few cups in a box that can receive only one on top of another (no adjacent cup). When it comes time to get one of those cups, you must first access the last one that was added. This technique of building a list is referred to as first-in last-out (FILO).

To support stack types of collections, the .NET Framework provides the Stack class. Stack is a serializable class that implements the ICollection (giving the ability to know the number of items in the list) and the IEnumerable (which gives the ability to use foreach).

Creating a Stack

The Stack class is equipped with three constructors. The default constructor allows you to create a stack without primarily taking any action. Here is an example:

using namespace System;
using namespace System::Collections;

[Serializable]
public ref class Sport
{
    public String ^ Name;
    public unsigned int PlayersPerTeam;
}


{
    int  Main(string[] args)
    {
        Stack players = gcnew Stack();

        return 0;
    }
}

If you create a stack with this constructor, the list is primarily empty with a default capacity. If you want, before initializing the list, you can specify how much space the compiler should primarily allocate for the number of eventual items of the list. To provide this information, the Stack class is equipped with the following constructor:

public Stack(int initialCapacity);

Adding Items to a Stack

To add an item to a stack, you can call the Push() method of the Stack class. Its syntax is:

public virtual void Push(object obj);

The new item is passed as argument to the method. Here is an example:

using namespace System;
using namespace System::IO;
using namespace System::Collections;
using namespace System::Runtime::Serialization::Formatters::Binary;

[Serializable]
public ref class Sport
{
    public String ^ Name;
    public unsigned int PlayersPerTeam;
}


{
    int  Main(string[] args)
    {
        Stack players = gcnew Stack();
        Sport basketball = gcnew Sport();

        basketball.Name = L"Basketball";
        basketball.PlayersPerTeam = 5;
        players.Push(basketball);

        SaveSports(players);
        return 0;
    }

    void SaveSports(Stack stc)
    {
        FileStream fsSport = gcnew FileStream(L"Sports.spt",
                                            FileMode::Create,
                                            FileAccess::Write);
        BinaryFormatter bfSport = gcnew BinaryFormatter();

        bfSport->Serialize(fsSport, stc);
        fsSport->Close();
    }
}

Whenever you add a new item to the stack, the compiler increases the number of items in the list. This number is stored in the Count property of the Stack class.

If you have a series of items that were created using a class that implements the ICollection interface, you can use the following constructor of the Stack class:

public Stack(ICollection col);

 When using this constructor, pass a variable of collection class as argument. Here is an example:

using namespace System;
using namespace System::IO;
using namespace System::Collections;
using namespace System::Runtime::Serialization::Formatters::Binary;

[Serializable]
public ref class Sport
{
    public String ^ Name;
    public unsigned int PlayersPerTeam;
}


{
    int  Main(string[] args)
    {
        Sport spt = gcnew Sport();
        ArrayList lstSports = gcnew ArrayList();

        spt.Name = L"Volleyball";
        spt.PlayersPerTeam = 6;
        lstSports->Add(spt);

        spt = gcnew Sport();
        spt.Name = L"Tennis Single";
        spt.PlayersPerTeam = 1;
        lstSports->Add(spt);

        spt = gcnew Sport();
        spt.Name = L"Handball";
        spt.PlayersPerTeam = 6;
        lstSports->Add(spt);

        Stack sports = gcnew Stack(lstSports);

        SaveSports(sports);
        return 0;
    }

    void SaveSports(Stack stc)
    {
        FileStream fsSport = gcnew FileStream(L"Sports.spt",
                                            FileMode::Create,
                                            FileAccess::Write);
        BinaryFormatter bfSport = gcnew BinaryFormatter();

        bfSport->Serialize(fsSport, stc);
        fsSport->Close();
    }
}

Accessing an Item in the Stack

As mentioned previously, the Stack class overrides the GetEnumerator() method by implementing the IEnumerable interface. This allows you to access each member of the stack using the foreach loop. Here is an example:

using namespace System;
using namespace System::IO;
using namespace System::Collections;
using namespace System::Runtime::Serialization::Formatters::Binary;

[Serializable]
public ref class Sport
{
    public String ^ Name;
    public unsigned int PlayersPerTeam;
}


{
    int  Main(string[] args)
    {
        Stack sports = OpenSports();

        for each(Sport spt in sports)
        {
            Console::WriteLine(L"=-+-+-+-+-= Sport =-+-+-+-+-=");
            Console::WriteLine(L"Sport Name:   {0}", spt.Name);
            Console::WriteLine(L"Players/Team: {0}", spt.PlayersPerTeam);
        }

        Console::WriteLine();
        return 0;
    }

    void SaveSports(Stack stc)
    {
        FileStream fsSport = gcnew FileStream(L"Sports.spt",
                                            FileMode::Create,
                                            FileAccess::Write);
        BinaryFormatter bfSport = gcnew BinaryFormatter();

        bfSport->Serialize(fsSport, stc);
        fsSport->Close();
    }

    Stack OpenSports()
    {
        FileStream fsSport = gcnew FileStream(L"Sports.spt",
                                            FileMode::Open,
                                            FileAccess::Read);
        BinaryFormatter bfSport = gcnew BinaryFormatter();

        Stack games = (Stack)bfSport.Deserialize(fsSport);
        fsSport->Close();

        return games;
    }
}

To find out if the list contains a particular item, you can call the Contains() method of the Stack class. Its syntax is:

public virtual bool Contains(object obj);

Removing Items From a Stack

As mentioned earlier, a stack is organized so that the last item that was added to the list is the first one to be removed. To support this operation, the Stack class is equipped with the Pop() method. Its syntax is:

public virtual object Pop();

When called, this method removed the last item in the stack. If you are interested to know what item was removed, this method returns it as an Object value.

Here is an example of calling the method:

using namespace System;
using namespace System::IO;
using namespace System::Collections;
using namespace System::Runtime::Serialization::Formatters::Binary;

[Serializable]
public ref class Sport
{
    public String ^ Name;
    public unsigned int PlayersPerTeam;
}


{
    int  Main(string[] args)
    {
        Stack sports = OpenSports();

        for each(Sport spt in sports)
        {
            Console::WriteLine(L"=-+-+-+-+-= Sport =-+-+-+-+-=");
            Console::WriteLine(L"Sport Name:   {0}", spt.Name);
            Console::WriteLine(L"Players/Team: {0}", spt.PlayersPerTeam);
        }

        Sport  one = (Sport)sports.Pop();

        Console::WriteLine(L"The sport removed was");
        Console::WriteLine(L"=-+-+-+-+-= Sport =-+-+-+-+-=");
        Console::WriteLine(L"Sport Name:   {0}", one.Name);
        Console::WriteLine(L"Players/Team: {0}", one.PlayersPerTeam);

        SaveSports(sports);
        sports = OpenSports();

        Console::WriteLine(L"=====================================");
        for each(Sport spt in sports)
        {
            Console::WriteLine(L"Sport Name:   {0}", spt.Name);
            Console::WriteLine(L"Players/Team: {0}", spt.PlayersPerTeam);
            Console::WriteLine(L"=-+-+-+-+-= Sport =-+-+-+-+-=");
        }
        
        Console::WriteLine();
        return 0;
    }

    void SaveSports(Stack stc)
    {
        FileStream fsSport = gcnew FileStream(L"Sports.spt",
                                            FileMode::Create,
                                            FileAccess::Write);
        BinaryFormatter bfSport = gcnew BinaryFormatter();

        bfSport->Serialize(fsSport, stc);
        fsSport->Close();
    }

    Stack OpenSports()
    {
        FileStream fsSport = gcnew FileStream(L"Sports.spt",
                                            FileMode::Open,
                                            FileAccess::Read);
        BinaryFormatter bfSport = gcnew BinaryFormatter();

        Stack games = (Stack)bfSport.Deserialize(fsSport);
        fsSport->Close();

        return games;
    }
}

The Pop() method is used to remove one item from the stack. To remove all items from the list, you can call the Clear() method whose syntax is:

public virtual void Clear();

Queue

 

Introduction

A queue is a technique of using a list so that the first item added to the list will be the first one to be removed. This is referred to as first-in first-out (FIFO). To illustrate it, when people stand in line at one cashier of a supermarket, the first customer in line in front of the cashier will be the first to be served and the first to leave the supermarket.

To support queues, the .NET Framework provides the serialized Queue class that implements both the ICollection and the IEnumerable interfaces.

Creating a Queue

To create a queue, you can declare a Queue variable using one of its four constructors. The default constructor allows you to start a list without primarily adding an item to it. Here is an example:

{
    int main()
    {
        Queue ^ que = gcnew Queue();

        return 0;
    }
}

After this declaration, the compiler reserves some default memory space for the variable. If you want to specify how much space should be primarily allocated for the variable, you can use the following constructor:

public Queue(int capacity);

Building a Queue

The action that consists of adding an item to the queue is called "enqueue". To perform this operation, you can call the Queue.Enqueue() method whose syntax is:

public virtual void Enqueue(object obj);

This method takes as argument the object you want to add to the queue and places it as the first candidate to be removed. Here are examples of calling the method:

using namespace System;
using namespace System::IO;
using namespace System::Collections;
using namespace System::Runtime::Serialization::Formatters::Binary;

public enum Majors
{
    English,
    Nursing,
    Accounting,
    ComputerSciences,
    BusinessManagement,
    MathematicalSciences,
    HumanResourceDevelopment
}

[Serializable]
public ref class CStudent
{
    public String ^ FullName;
    public DateTime DateOfBirth;
    public Majors Major;
}


{
    int main()
    {
        Queue ^ que = gcnew Queue();
        CStudent ^ std = nullptr;

        std = gcnew CStudent;
        std->FullName = L"Donald Palau";
        std->DateOfBirth = gcnew DateTime(1988, 5, 12);
        std->Major = ComputerSciences;
        que.Enqueue(std);

        std = gcnew CStudent;
        std->FullName = L"Arlene Kafka";
        std->DateOfBirth = gcnew DateTime(1992, 8, 4);
        std->Major = BusinessManagement;
        que.Enqueue(std);

        std = gcnew CStudent;
        std->FullName = L"Hortense Moons";
        std->DateOfBirth = gcnew DateTime(1994, 10, 7);
        std->Major = MathematicalSciences;
        que.Enqueue(std);

        SaveStudents(que);
        return 0;
    }

    void SaveStudents(Queue ^ q)
    {
        FileStream ^ fsStudent = gcnew FileStream(L"Students.roh",
                                            FileMode::Create,
                                            FileAccess::Write);
        BinaryFormatter ^ bfStudent = gcnew BinaryFormatter();

        bfStudent->Serialize(fsStudent, q);
        fsStudent->Close();
    }

    Queue ^ OpenStudents()
    {
        FileStream ^ fsStudent = gcnew FileStream(L"Students.roh",
                                            FileMode::Open,
                                            FileAccess::Read);
        BinaryFormatter ^ bfStudent = gcnew BinaryFormatter();

        Queue pupils = (Queue)bfStudent.Deserialize(fsStudent);
        fsStudent->Close();

        return pupils;
    }
}

If you already have a list created from a class that implements the ICollection interface, you can create a queue based on that list. To do this, you would use the following constructor of the Queue class:

public Queue(ICollection col);

This constructor accepts an ICollection implementer as argument. Here is an example:

using namespace System;

public enum Majors
{
    English,
    Nursing,
    Accounting,
    ComputerSciences,
    BusinessManagement,
    MathematicalSciences,
    HumanResourceDevelopment
}

public ref class CStudent
{
    public String ^ FullName;
    public DateTime DateOfBirth;
    public Majors Major;
}


{
    int main()
    {
        CStudent ^ std = nullptr;
        ArrayList lstStudents = gcnew ArrayList();

        std = gcnew CStudent;
        std->FullName = L"Hermine Justice";
        std->DateOfBirth = gcnew DateTime(1990, 3, 24);
        std->Major = English;
        lstStudents->Add(std);

        std = gcnew CStudent;
        std->FullName = L"Patricia Palermo";
        std->DateOfBirth = gcnew DateTime(1989, 12, 20);
        std->Major = BusinessManagement;
        lstStudents->Add(std);

        Queue ^ que = gcnew Queue(lstStudents);
        
        return 0;
    }
}

Retrieving the Items From a Queue

Remember that the first item added to a queue stays in front of all others that would be added. To get (only) the first item of a queue, the Queue class is equipped with a method named Peek(). Its syntax is:

public virtual object Peek();

This method returns an Object object that represents the first item of the queue (remember to cast it to your particular object if necessary). Here are two examples of calling it:

using namespace System;
using namespace System::Collections;

public enum Majors
{
    English,
    Nursing,
    Accounting,
    ComputerSciences,
    BusinessManagement,
    MathematicalSciences,
    HumanResourceDevelopment
}

public ref class CStudent
{
    public String ^ FullName;
    public DateTime DateOfBirth;
    public Majors Major;
}


{
    int main()
    {
        Queue ^ que = gcnew Queue();
        CStudent ^ std = nullptr;

        std = gcnew CStudent;
        std->FullName = L"Donald Palau";
        std->DateOfBirth = gcnew DateTime(1988, 5, 12);
        std->Major = ComputerSciences;
        que.Enqueue(std);

        std = gcnew CStudent;
        std->FullName = L"Arlene Kafka";
        std->DateOfBirth = gcnew DateTime(1992, 8, 4);
        std->Major = BusinessManagement;
        que.Enqueue(std);

        Console::WriteLine(L"The current first item of the queue is");
        Student s1 = (Student)que.Peek();
        Console::WriteLine(L"== Student Information ==");
        Console::WriteLine(L"Full Name:     {0}", s1.FullName);
        Console::WriteLine(L"Date of Birth: {0:d}", s1.DateOfBirth);
        Console::Write(L"Major:         ");
        switch (s1.Major)
        {
            case English:
                Console::WriteLine(L"English");
                break;
            case Nursing:
                Console::WriteLine(L"Nursing");
                break;
            case Accounting:
                Console::WriteLine(L"Accounting");
                break;
            case ComputerSciences:
                Console::WriteLine(L"Computer Sciences");
                break;
            case BusinessManagement:
                Console::WriteLine(L"Business Management");
                break;
            case MathematicalSciences:
                Console::WriteLine(L"Mathematical Sciences");
                break;
            case HumanResourceDevelopment:
                Console::WriteLine(L"Human Resource Development");
                break;
        }

        Console::WriteLine(L"--------------------------------------------");

        std = gcnew CStudent;
        std->FullName = L"Hortense Moons";
        std->DateOfBirth = gcnew DateTime(1994, 10, 7);
        std->Major = MathematicalSciences;
        que.Enqueue(std);

        Console::WriteLine(L"The current first item of the queue is");
        Student s2 = (Student)que.Peek();
        Console::WriteLine(L"== Student Information ==");
        Console::WriteLine(L"Full Name:     {0}", s2.FullName);
        Console::WriteLine(L"Date of Birth: {0:d}", s2.DateOfBirth);
        Console::Write(L"Major:         ");
        switch (s2.Major)
        {
            case English:
                Console::WriteLine(L"English");
                break;
            case Nursing:
                Console::WriteLine(L"Nursing");
                break;
            case Accounting:
                Console::WriteLine(L"Accounting");
                break;
            case ComputerSciences:
                Console::WriteLine(L"Computer Sciences");
                break;
            case BusinessManagement:
                Console::WriteLine(L"Business Management");
                break;
            case MathematicalSciences:
                Console::WriteLine(L"Mathematical Sciences");
                break;
            case HumanResourceDevelopment:
                Console::WriteLine(L"Human Resource Development");
                break;
        }

        Console::WriteLine(L"--------------------------------------------");

        return 0;
    }
}

This would produce:

The current first item of the queue is
== Student Information ==
Full Name:     Donald Palau
Date of Birth: 5/12/1988
Major:         Computer Sciences
--------------------------------------------
The current first item of the queue is
== Student Information ==
Full Name:     Donald Palau
Date of Birth: 5/12/1988
Major:         Computer Sciences
--------------------------------------------
Press any key to continue . . .

To give you access to the items of a queue, the Queue class overrides the GetEnumerator() method of the IEnumerable class that it implements. This allows you to use the foreach loop to continuously enumerate the members of a queue. Here is an example:

using namespace System;
using namespace System::IO;
using namespace System::Collections;
using namespace System::Runtime::Serialization::Formatters::Binary;

public enum Majors
{
    English,
    Nursing,
    Accounting,
    ComputerSciences,
    BusinessManagement,
    MathematicalSciences,
    HumanResourceDevelopment
}

[Serializable]
public ref class CStudent
{
    public String ^ FullName;
    public DateTime DateOfBirth;
    public Majors Major;
}

int main()
{
        CStudent ^ std = nullptr;
        Queue ^ lstStudents = OpenStudents();

        std = gcnew CStudent;
        std->FullName = L"Hermine Justice";
        std->DateOfBirth = gcnew DateTime(1990, 3, 24);
        std->Major = English;
        lstStudents->Enqueue(std);

        std = gcnew CStudent;
        std->FullName = L"Patricia Palermo";
        std->DateOfBirth = gcnew DateTime(1989, 12, 20);
        std->Major = BusinessManagement;
        lstStudents->Enqueue(std);

        SaveStudents(lstStudents);
        lstStudents = OpenStudents();
        ShowStudents(lstStudents);

        return 0;
    }

    void ShowStudents(Queue ^ q)
    {
        for each(Student s in q)
        {
            Console::WriteLine(L"== Student Information ==");
            Console::WriteLine(L"Full Name:     {0}", s.FullName);
            Console::WriteLine(L"Date of Birth: {0:d}", s.DateOfBirth);
            Console::Write(L"Major:         ");
            switch (s.Major)
            {
                case English:
                    Console::WriteLine(L"English");
                    break;
                case Nursing:
                    Console::WriteLine(L"Nursing");
                    break;
                case Accounting:
                    Console::WriteLine(L"Accounting");
                    break;
                case ComputerSciences:
                    Console::WriteLine(L"Computer Sciences");
                    break;
                case BusinessManagement:
                    Console::WriteLine(L"Business Management");
                    break;
                case MathematicalSciences:
                    Console::WriteLine(L"Mathematical Sciences");
                    break;
                case HumanResourceDevelopment:
                    Console::WriteLine(L"Human Resource Development");
                    break;
            }

            Console::WriteLine(L"--------------------------------------------");
        }
    }

    void SaveStudents(Queue ^ q)
    {
        FileStream ^ fsStudent = gcnew FileStream(L"Students.roh",
                                            FileMode::Create,
                                            FileAccess::Write);
        BinaryFormatter ^ bfStudent = gcnew BinaryFormatter();

        bfStudent->Serialize(fsStudent, q);
        fsStudent->Close();
    }

    Queue ^ OpenStudents()
    {
        FileStream ^ fsStudent = gcnew FileStream(L"Students.roh",
                                            FileMode::Open,
                                            FileAccess::Read);
        BinaryFormatter ^ bfStudent = gcnew BinaryFormatter();

        Queue pupils = (Queue)bfStudent.Deserialize(fsStudent);
        fsStudent->Close();

        return pupils;
    }
}

This would produce:

== Student Information ==
Full Name:     Donald Palau
Date of Birth: 5/12/1988
Major:         Computer Sciences
--------------------------------------------
== Student Information ==
Full Name:     Arlene Kafka
Date of Birth: 8/4/1992
Major:         Business Management
--------------------------------------------
== Student Information ==
Full Name:     Hortense Moons
Date of Birth: 10/7/1994
Major:         Mathematical Sciences
--------------------------------------------
== Student Information ==
Full Name:     Hermine Justice
Date of Birth: 3/24/1990
Major:         English
--------------------------------------------
== Student Information ==
Full Name:     Patricia Palermo
Date of Birth: 12/20/1989
Major:         Business Management
--------------------------------------------
Press any key to continue . . .

Removing Items From a Queue

The process of removing an item from a queue is called "dequeue". To assist you with performing this operation, the Queue class is equipped with a method named Dequeue. Its syntax is:

public virtual object Dequeue();

The primary purpose of this method is to delete the first item of the Queue list. If you are interested to know what item was deleted, this method returns it.

To remove all items from the queue, you can call the Clear() method of the class. Its syntax is:

public virtual void Clear();

Home Copyright © 2025, FunctionX 14 October 2008, 10:12 Home