Home > Articles > Programming > Windows Programming

Working with New Abstract Data Types in Visual Basic .NET

  • Print
  • + Share This
This straightforward, comprehensive coverage of the Visual Basic .NET collection types includes summary tables listing methods of each type and advice about when to choose one type over another.
This article is excerpted from Chapter 3, "Basic Programming in Visual Basic .NET," of Visual Basic .NET Unleashed, by Paul Kimmel (Sams Publishing; ISBN 067232234x).
This chapter is from the book

This chapter is from the book

A revised Collection class similar to the VB6 Collection is defined in the Microsoft.VisualBasic namespace. Visual Basic .NET has added several new Abstract Data Types (ADTs) to ultimately replace the Collection class. The names of the new classes were enumerated in Chapter 2, including an example of using the Stack class. The subsections that follow demonstrate ArrayList, HashTable, SortedList, and Queue.

Members of ArrayList

The ArrayList class is a designed replacement for an unadorned array. Although arrays in Visual Basic .NET are classes, they are designed to work similarly to VB6 arrays. This means you have to resize the arrays and preserve elements manually, which is likely to yield code that is littered with ReDim statements.

Dynamic array sizing is semantical behavior that belongs to an array. In an object-oriented programming language, you would expect that such behavior is defined as part of an array class. Combining storage and capacity management in a single class is what ArrayList has to offer. You will find ArrayList easier to use than a System.Array or the VB6-style collection.

Table 3.1 lists the members of ArrayList.

Table 3.1 ArrayList Members



Shared Method


Wraps an ArrayList around an object that implements IList


Returns a fixed-size wrapper, allowing elements to be modified but not added or removed


Returns a read-only wrapper around an ArrayList


Returns an ArrayList containing multiple copies of the argument value


Returns a thread-safe list wrapper

Instance Property


Used to get or change the capacity of an ArrayList


Returns number of elements in the list; capacity may be greater than or equal to count


Returns a Boolean indicating whether or not the ArrayList has a fixed size


Returns a Boolean indicating whether or not the ArrayList is read-only


Returns a Boolean indicating whether or not access to the ArrayList is synchronized


Used to index elements of the ArrayList


Returns an object used to synchronize ArrayList access

Instance Method


Appends an element to the ArrayList, increasing the capacity if necessary


Appends elements from an ICollection


Searches for element using binary algorithm


Removes all elements


Performs shallow copy of all elements


Returns a Boolean indicating whether or not the element is in the ArrayList


Copies all or part of the ArrayList to a one-dimensional System.Array


Determines whether the argument array references the calling array


Returns ArrayList enumerator


Hashing function inherited from Object


Copies range of elements to a new ArrayList


Returns metaclass of ArrayList; inherited from Object


Returns the index of a particular element of the array list


Inserts an element into the list at specified index


Inserts a range of elements at specified index


Returns the index of the last occurrence of object


Removes the first instance of argument object


Removes element at specified index


Removes a range of elements at specified index


Sorts the array in reverse order


Copies range of elements over the elements in the ArrayList


Reorders the data in ascending order


Copies elements to System.Array


Returns name of object


Sets capacity to number of elements

The next section demonstrates some of the characteristics of ArrayList.

Using ArrayList

The biggest benefit of ArrayList over System.Array is that ArrayList has dynamic capacity management built in. When you use System.Array, you have to make sure there is enough room for an element. If not, you have to add capacity to the array with ReDim. On the other hand, if you use the ArrayList Add, AddRange, Insert, or InsertRange methods, the capacity is adjusted as needed.

ArrayList has significant advantages over VB6 arrays but fewer advantages over Visual Basic .NET System.Array; however, capacity management is enough of a reason to prefer ArrayList over System.Array. Many of the methods in ArrayList are similar to methods in Array (see "Using Array Methods"); therefore, we will not repeat examples of those methods here. Capacity management and adding and managing a range of elements are additional features offered in ArrayList. Let's take a look at examples of using these behaviors. Listing 3.4 demonstrates behaviors of ArrayList that are not found in System.Array.

Listing 3.4 Behaviors of ArrayList not found in System.Array.

 1: Sub DemoSetRange()
 3:  Dim MyArray As New ArrayList()
 5:  Dim Array1() As Integer = {0, 1, 2, 3, 4, 5}
 7:  MyArray.InsertRange(0, Array1)
 9:  Dim I As Integer
11:  For I = 0 To MyArray.Count
12:   Debug.WriteLine(MyArray(I))
13:  Next
15:  Debug.WriteLine("Contains 3? " & MyArray.Contains(3))
17: End Sub

The example declares an ArrayList named MyArray using one of three possible constructors. The constructor on line 3 takes no parameters. Line 5 allocates a System.Array and initializes the members to the integers 0 through 5. Line 7 demonstrates ArrayList.InsertRange. InsertRange takes a start index and an ICollection object. System.Array implements the ICollection interface, so System.Array is a suitable argument for InsertRange. In fact, any class that implements ICollection (HashTable, Stack, Queue, and SortedList are other examples) is a suitable argument for InsertRange. Lines 11 through 13 demonstrate that elements of an ArrayList can be accessed as if it were a simple array. (Of course you can use the new Enumerator behavior that you saw in Listing 3.2, as well.)

Line 15 demonstrates the Contains method. Contains takes an object, which can be a literal integer like 3, and returns a Boolean indicating whether or not the object is in the ArrayList. In the example, Option Strict is On so the Boolean returned by Contains is printed using the ToString method of the Boolean type.


Hash tables use key and value pairs. The key is processed through a hashing function that is designed to generate a unique value that is then used as an index into the hash table to the location containing the value. Hash tables strike a balance between resource usage and speed.

Instead of probing each element for equality to determine whether objects are equal, simply processing the key provides an index to the location that contains the associated value. There is a significant amount of research on hash tables, hashing functions, and key-collision avoidance. (You may have studied some of them in college if you were a computer science major, but the .NET Framework provides a HashTable implemented for you.)

The System.Collections.HashTable class implements a hash table available for you to use. HashTable works externally much like a data dictionary. Provide a unique key and an associated value, and the HashTable takes care of the rest.

Suppose you were storing personnel records in memory for quick access. You might key each record on the Social Security number, and the value would be the personnel record. (For the demonstration, we will simply store a person's name to represent the personnel record.)

Listing 3.5 declares a new instance of a hash table and adds some unique elements to the hash table keyed on pseudo-Social Security numbers. The values stored in the hash table represent the data associated with the keys. (The key is the first argument and the value is the second argument of the Add method.)

Listing 3.5 Storing items in a hash table.

 1: Sub DemoHashTable()
 2:  Dim Hash As New Hashtable()
 3:  Hash.Add("555-55-5555", "Frank Arndt")
 4:  Hash.Add("555-55-5556", "Mary Bonnici")
 5:  Hash.Add("555-55-5557", "Paul Kimmel")
 7:  Dim Enumerator As IDictionaryEnumerator = Hash.GetEnumerator
 9:  While (Enumerator.MoveNext())
10:   Debug.WriteLine(Enumerator.Key & "=" & _
11:    Enumerator.Value)
12:  End While
14: End Sub


Enumerator objects are read-only. To modify elements of a collection like a HashTable, you can use a For Next loop, indexing the elements of the collection directly.

HashTable uses an IDictionaryEnumerator object to iterate over elements. Line 7 declares an enumerator and lines 9 through 12 iterate over each element displaying the key and value pairs. (.Key and .Value were not defined in the IEnumerator interface; they were added in the IDictionaryEnumerator.)


The SortedList ADT is based on the dictionary interface. Recall from the last section that a dictionary is a collection of key (or name) and value pairs. SortedList maintains two internal arrays. One keeps track of keys and the second keeps track of values. As with a hash table, the key values of a sorted list must be unique.

SortedList has methods similar to ArrayList, in addition to the key and value pairs introduced with HashTable. SortedList is defined in the System.Collections namespace. For more information on SortedList, look in the MSDN help files.


Queue data structures are also referred to as First In First Out (FIFO) data structures. Think of a queue as a line. There is a first in line, a last in line, and everything in between.

Just as Stacks have a language for adding elements to the collection—Push and Pop—to denote adding and removing elements to a Stack, Queue uses the notion of enqueuing and dequeuing. All of the collection-based ADTs work with Objects; hence to enqueue means to add an Object to the queue and to dequeue means to remove an object from the queue.

Queues are a natural choice when you want the first item put into a collection to be the first item out. Listing 3.6 demonstrates basic queue behavior.

Listing 3.6 Basic queue behavior.

 1: Sub DemoQueue()
 3:  Dim Q As New Queue()
 4:  Q.Enqueue("One")
 5:  Q.Enqueue("Two")
 7:  While (Q.Count > 0)
 8:   Debug.WriteLine(Q.Dequeue)
 9:  End While
11: End Sub

The output from Listing 3.6 is One and Two. The elements are dequeued in exactly the same order in which they were enqueued.

Queues implement several of the same COM interfaces as other ADTs defined in the System.Collections namespace, like ICollection, IEnumerable, and ICloneable. For this reason queues have many of the same operations by name as other ADTs.

Assessing the ADTs

For general purpose in-memory storage, ArrayList will suffice. For key and value pairs, use HashTable or SortedList. If you want objects stored and retrieved in the same order, use Queue, and if you want the last element put into a collection to be the first one out, use Stack. The fundamental behaviors of the collection classes are identical. The semantic operations are consistent with the type of data structure.

  • + Share This
  • 🔖 Save To Your Account