C# Generics: Collection Interfaces
Pages: 1, 2, 3, 4, 5, 6, 7
Queues
A queue represents a first-in, first-out (FIFO) collection. The classic analogy is to a line (or queue if you are British) at a ticket window. The first person in line ought to be the first person to come off the line to buy a ticket.
A queue is a good collection to use when you are managing a limited resource. For example, you might want to send messages to a resource that can handle only one message at a time. You would then create a message queue so that you can say to your clients: "Your message is important to us. Messages are handled in the order in which they are received."
The Queue class has
a number of member methods and properties, as shown in Table 9-4.
Table 9-4. Queue methods and properties
|
Method or property |
Purpose |
|---|---|
|
|
Public property that gets the number of elements in the
|
|
|
Removes all objects from the |
|
|
Determines if an element is in the |
|
|
Copies the |
|
|
Removes and returns the object at the beginning of the
|
|
|
Adds an object to the end of the |
|
|
Returns an enumerator for the |
|
|
Returns the object at the beginning of the |
|
|
Copies the elements to a new array. |
Add
elements to your queue with the Enqueue command
and take them off the queue with Dequeue or by
using an enumerator. Example 9-16 illustrates.
Example 9-16. Working with a queue
#region Using directives
using System;
using System.Collections.Generic;
using System.Text;
#endregion
namespace Queue
{
public class Tester
{
static void Main( )
{
Queue<Int32> intQueue = new Queue<Int32>( );
// populate the array
for ( int i = 0; i < 5; i++ )
{
intQueue.Enqueue( i * 5 );
}
// Display the Queue.
Console.Write( "intQueue values:\t" );
PrintValues( intQueue );
// Remove an element from the queue.
Console.WriteLine(
"\n(Dequeue)\t{0}", intQueuee.Dequeue( ) );
// Display the Queue.
Console.Write( "intQueue values:\t" );
PrintValues( intQueue );
// Remove another element from the queue.
Console.WriteLine(
"\n(Dequeue)\t{0}", intQueuee.Dequeue( ) );
// Display the Queue.
Console.Write( "intQueue values:\t" );
PrintValues( intQueue );
// View the first element in the
// Queue but do not remove.
Console.WriteLine(
"\n(Peek) \t{0}", intQueuee.Peek( ) );
// Display the Queue.
Console.Write( "intQueue values:\t" );
PrintValues( intQueue );
}
public static void PrintValues(IEnumerable<Int32> myCollection)
{
IEnumerator<Int32> myEnumerator =
myCollection.GetEnumerator( );
while ( myEnumerator.MoveNext( ) )
Console.Write( "{0} ", myEnumerator.Current );
Console.WriteLine( );
}
}
}
Output:
intQueue values: 0 5 10 15 20
(Dequeue) 0
intQueuee values: 5 10 15 20
(Dequeue) 5
intQueue values: 10 15 20
(Peek) 10
intQueue values: 10 15 20
In this example the List is replaced by a
Queue. I've dispensed with the
Employee class to save room, but of course you can
Enqueue user-defined objects as well.
The output shows that queuing objects adds them to the
Queue, and calls to Dequeue
return the object and also remove them from the
Queue. The Queue class also
provides a Peek() method that allows you to see,
but not remove, the first element.
Because the Queue class is enumerable, you can
pass it to the
PrintValues method, which is provided as an
IEnumerable interface. The conversion is
implicit. In the PrintValues method you call
GetEnumerator, which you will remember is the
single method of all IEnumerable classes. This
returns an
IEnumerator, which you then use to enumerate all
the objects in the collection.
Stacks
A stack is a last-in, first-out (LIFO) collection, like a stack of dishes at a buffet table, or a stack of coins on your desk. A dish added on top is the first dish you take off the stack.
The principal methods for adding to and removing from a stack are
Push() and Pop();
Stack also offers a Peek()
method, very much like Queue. The significant
methods and properties for
Stack are
shown in Table 9-5.
Table 9-5. Stack methods and properties
|
Method or property |
Purpose |
|---|---|
|
|
Public property that gets the number of elements in the
|
|
|
Removes all objects from the |
|
|
Creates a shallow copy. |
|
|
Determines if an element is in the |
|
|
Copies the |
|
|
Returns an enumerator for the |
|
|
Returns the object at the top of the |
|
|
Removes and returns the object at the top of the
|
|
|
Inserts an object at the top of the |
|
|
Copies the elements to a new array. |
The List, Queue, and
Stack types contain overloaded
CopyTo( ) and ToArray( ) methods
for copying their elements to an array. In the case of a
Stack, the CopyTo( ) method will
copy its elements to an existing one-dimensional array, overwriting
the contents of the array beginning at the index you specify. The
ToArray( ) method returns a new array with the
contents
of the stack's elements. Example 9-17 illustrates.
Example 9-17. Working with a stack
#region Using directives
using System;
using System.Collections.Generic;
using System.Text;
#endregion
namespace Stack
{
public class Tester
{
static void Main( )
{
Stack<Int32> intStack = new Stack<Int32>( );
// populate the array
for ( int i = 0; i < 8; i++ )
{
intStack.Push( i * 5 );
}
// Display the Stack.
Console.Write( "intStack values:\t" );
PrintValues( intStack );
// Remove an element from the stack.
Console.WriteLine( "\n(Pop)\t{0}",
intStack.Pop( ) );
// Display the Stack.
Console.Write( "intStack values:\t" );
PrintValues( intStack );
// Remove another element from the stack.
Console.WriteLine( "\n(Pop)\t{0}",
intStack.Pop( ) );
// Display the Stack.
Console.Write( "intStack values:\t" );
PrintValues( intStack );
// View the first element in the
// Stack but do not remove.
Console.WriteLine( "\n(Peek) \t{0}",
intStack.Peek( ) );
// Display the Stack.
Console.Write( "intStack values:\t" );
PrintValues( intStack );
// declare an array object which will
// hold 12 integers
int[] targetArray = new int[12];
for (int i = 0; i < targetArray.Length; i++)
{
targetArray[i] = i * 100 + 100;
}
// Display the values of the target Array instance.
Console.WriteLine( "\nTarget array: " );
PrintValues( targetArray );
// Copy the entire source Stack to the
// target Array instance, starting at index 6.
intStack.CopyTo( targetArray, 6 );
// Display the values of the target Array instance.
Console.WriteLine( "\nTarget array after copy: " );
PrintValues( targetArray );
}
public static void PrintValues(
IEnumerable<Int32> myCollection )
{
IEnumerator<Int32> enumerator =
myCollection.GetEnumerator( );
while ( enumerator.MoveNext( ) )
Console.Write( "{0} ", enumerator.Current );
Console.WriteLine( );
}
}
}
Output:
intStack values: 35 30 25 20 15 10 5 0
(Pop) 35
intStack values: 30 25 20 15 10 5 0
(Pop) 30
intStack values: 25 20 15 10 5 0
(Peek) 25
intStack values: 25 20 15 10 5 0
Target array:
100 200 300 400 500 600 700 800 900 0 0 0
Target array after copy:
100 200 300 400 500 600 25 20 15 10 5 0
The new array:
25 20 15 10 5 0
The output reflects that the items pushed onto the stack were popped in reverse order.
The effect of CopyTo() can be
seen by examining the target array before and after calling
CopyTo( ). The array elements are overwritten
beginning with the index specified (6).

