Visual Basic .NET Collections

Visual Basic .NET Collections

We covered arrays pretty thoroughly, and now as promised it's time to take a look at collections. In the Visual Basic .NET development environment, the advanced visual tools in the toolbox contain collections. The TreeView class has a Nodes collection, and the ListView class has a ListItem collection. In short, you have to understand collections to use the advanced controls and many of the framework classes. Visual Basic .NET also provides several collection classes ready for use.

An array is really considered a simple collection. A collection is just what you think it would be—a group or collection of objects. As an array inherits from the System.Array namespace, collections inherit from the System.Collections namespace. Collections are so useful that the System.Collections namespace contains interfaces and classes that define various collections of objects, such as array lists, hash tables, queues, stacks, and dictionaries. So, you can easily create your own collection of anything you might need. For those of you who have taken a college class in data structures, these terms will be familiar. In any event, I'll briefly touch on some of them to illustrate their differences and describe when you would want to use one over another.

The ArrayList Collection

Despite its name, the new ArrayList collection type is found in the System.Collections namespace. The ArrayList type is popular in the Java language, and now the same functionality is available in Visual Basic .NET.

As you can with an array, you can add items to an ArrayList collection. However, the first difference to note between an array and an ArrayList is that you don't have to provide an index for each item. Why? Collections automatically grow or shrink as you add or delete items. You don't have to keep track of the number of items you are adding and then issue a ReDim or ReDim Preserve statement to adjust the size of the structure. To give you an idea of an array list, let's convert our list of Hercules' labors from an array to an ArrayList collection.

Dim salLaborsOfHercules As New ArrayList() With salLaborsOfHercules .Add("Kill Nemean Lion") .Add("Slay nine-headed hydra of Lerna") .Add("Capture elusive Stag of Arcadia") .Add("Capture wild boar on Mt. Erymantus") .Add("Clean Stables of King Augeas of Elis") .Add("Shoot monstrous man-eating birds of the " & _ Stymphalian Marshes") .Add("Capture mad bull of Crete") .Add("Kill man-eating mares of King Diomedes") .Add("Steal Girdle of Hippolyta") .Add("Seize cattle of Geryon of Erytheia") .Add("Fetch golden apples of Hesperides") .Add("Retrieve three-headed dog Cerberus from Hell") .Add("Learn Visual Basic .NET") End With

Now let's examine some metrics of our ArrayList using the code below. The output is shown in Figure 6-13.

MessageBox.Show("Array count is: " & _ salLaborsOfHercules.Count() & _ " Array capacity is: " & _ salLaborsOfHercules.Capacity(), & _ "To do today")

Figure 6-13

ArrayList metrics.

The Capacity property contains the number of elements that the ArrayList is capable of storing. The Count property contains the number of elements that are actually in the ArrayList. The capacity will always be greater than or equal to the count. If the count exceeds the capacity while you are adding elements, the capacity of the list is immediately doubled by automatically reallocating the internal array.

You can explicitly set the value of the Capacity property. When you set the value, the underlying internal array is also reallocated to accommodate the specified capacity. If the capacity is explicitly set to zero, the common language runtime sets it to the default capacity instead. As you can see in Figure 6-13, the default capacity is 16.

Let's say that we add all of the contents to an ArrayList and know that no additional elements will be added. We can call the TrimToSize method to reduce a list's memory overhead.

salLaborsOfHercules.TrimToSize()

In Figure 6-14, you can see that the capacity is now the same as the count.

Figure 6-14

TrimToSize reduces a list's memory overhead.

To completely clear all the elements from a list, call the Clear method before calling TrimToSize. Trimming an empty ArrayList sets the capacity to the default capacity, not to zero. Figure 6-15 shows the results.

salLaborsOfHercules.Clear() 'Clears the contents salLaborsOfHercules.TrimToSize() 'Resets the capacity ' to the default MessageBox.Show("Array count is: " & _ salLaborsOfHercules.Count() & _ "Array capacity is: " & _ salLaborsOfHercules.Capacity(), _ "To do today")

Figure 6-15

The Clear method clears all elements from a list. A subsequent call to TrimToSize resets the list to the default capacity.

If you want to iterate through a collection such as the ArrayList, you simply use a For Each statement, as shown here and in Figure 6-16:

Dim sCollectionItem As String = "" 'Holds each item in turn Dim sOutputString As String = "" 'Holds the output of ' all items For Each sCollectionItem In salLaborsOfHercules sOutputString += sCollectionItem & CtrlChr.CrLf Next MessageBox.Show(sOutputString, "Array List Iteration")

Figure 6-16

The For Each statement makes it easy to iterate through a list.

Queues

A queue is a standard data structure that provides a first in/first out (FIFO) capability. Many times an analogy is drawn to a line at a movie theater. Everyone is in line, but the first one in line is the first one admitted to the movie.

Queues are useful for storing messages in the order that they are received for sequential processing. The Queue class implements the structure as a circular array, which means that objects stored in a queue are inserted at one end and removed from the other. As with the ArrayList collection, when the number of elements in the queue reaches its capacity, the capacity is automatically increased to accommodate more elements.

We use the queue's EnQueue method to add an object to the tail of a queue.

Dim qWordQueue As New Queue() With qWordQueue .Enqueue("It ") .Enqueue("was ") .Enqueue("the ") .Enqueue("best ") .Enqueue("of ") .Enqueue("times. ") End With 

When you want to retrieve items from the queue, you evoke the DeQueue method. This method returns the items in a FIFO sequence. Using the MoveNext method, you can ensure that you don't walk off the end of the queue.

Dim sTaleOfTwoCities As String = "" While qWordQueue.GetEnumerator.MoveNext sTaleOfTwoCities += qWordQueue.Dequeue.ToString() End While

You also use the DeQueue method to remove items from the queue. The item is removed from the head of the queue if it's not empty. Otherwise, as with our friend the array, we get a null reference.

MessageBox.Show(sTaleOfTwoCities & _ "Item count: " & qWordQueue.Count, _ "Queue - DeQueue")

You can see in Figure 6-17 that we have dequeued all of the elements in the queue.

Figure 6-17

The DeQueue method removes elements from a queue.

If you want to iterate over a queue without actually eliminating any items, the For Each construct works here as well. The following code sample iterates the queue and displays each element without removing it.

Dim sQueueItem As String = "" Dim sTaleOfTwoCities As String = "" For Each sQueueItem In qWordQueue sTaleOfTwoCities += sQueueItem Next MessageBox.Show(sTaleOfTwoCities & _ "Item count: " & qWordQueue.Count, _ "Queue - For Each")

You can see the results in Figure 6-18.

Figure 6-18

The For Each statement iterates through queues as well as lists.

You can determine whether a specific object exists in the queue by using the Contains method, which returns a Boolean True or False. However, there must be an exact match. Notice in the following code that an empty space appears after the word was. If the space were not included, the method would return False.

MessageBox.Show(qWordQueue.Contains("was ").ToString()) ' True

If you need to take a look at the head of the queue (the first item), use the Peek method. The Peek method returns the object at the head of the queue without removing it.

qWordQueue.Peek()

You always want to check a queue's Count property before attempting to reference an element to be sure that the queue is not empty. As with an ArrayList, if you try to reference an element that is no longer in the queue, a null reference results. However, anticipating that the queue (or the array for that matter) might be empty is simply good defensive programming. Both structures have the information built in to tell you whether accessing a specific element is safe. Always use this information or your user will be greeted with a "Queue empty" message like the one shown in Figure 6-19.

Figure 6-19

Attempting to dequeue an element from an empty queue causes this run-time error.

Stacks

Conceptually, stacks are the opposite of queues. Stacks are last in/first out (LIFO) structures. The analogy used to describe a stack is a spring-loaded plate holder found in school cafeterias. The first plate in is the bottommost and is the last one to be removed. The last plate inserted is at the top and is the first one someone grabs. The terminology used for a stack is to push an item onto a stack and to pop an item off a stack. Most of what you just learned about queues applies to stacks as well.

Dim qWordStack As New Stack() With qWordStack .Push("It ") .Push("was ") .Push("the ") .Push("best ") .Push("of ") .Push("times. ") End With Dim sTaleOfTwoCities As String = "" While qWordStack.GetEnumerator.MoveNext sTaleOfTwoCities += qWordStack.Pop.ToString() End While

The difference between the queue and the stack is that the last item pushed on the stack ("times." in our example) will now be the first one popped off the stack. Internally, the stack is implemented as a circular buffer.

MessageBox.Show(sTaleOfTwoCities & _ "Item count: " & qWordStack.Count, "Stack")

Figure 6-20 shows the LIFO order of a stack.

Figure 6-20

A stack processes items in LIFO order.

A stack has a handy ToArray method that copies the contents of a stack to an array. The elements are copied to the array in a last-in-first-out order. This order is identical to the one the items would be returned in from a succession of calls to a stack's Pop method.



Coding Techniques for Microsoft Visual Basic. NET
Coding Techniques for Microsoft Visual Basic .NET
ISBN: 0735612544
EAN: 2147483647
Year: 2002
Pages: 123
Authors: John Connell

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net