Collections: List and Dictionary
Prerequisites: Arrays
Arrays have a fixed size. The generic collections in
System.Collections.Generic grow and shrink as needed.
List(Of T)
Module Program
Sub Main()
Dim items As New List(Of String) From {"apple", "banana"}
items.Add("cherry")
items.Insert(0, "avocado")
items.Remove("banana")
Console.WriteLine(items.Count)
Console.WriteLine(items(1))
Console.WriteLine(items.Contains("cherry"))
Console.WriteLine(items.IndexOf("cherry"))
items.Sort()
Console.WriteLine(String.Join(", ", items))
For Each item In items
Console.Write(item.ToUpper() & " ")
Next
Console.WriteLine()
End Sub
End Module
3
apple
True
2
apple, avocado, cherry
APPLE AVOCADO CHERRY
(Of String) is the type argument: a List(Of String) holds only
strings, and the compiler checks every Add. From { ... } is a
collection initializer.
Dictionary(Of TKey, TValue)
A dictionary maps keys to values with fast lookup:
Module Program
Sub Main()
Dim capitals As New Dictionary(Of String, String) From {
{"France", "Paris"},
{"Japan", "Tokyo"}
}
capitals("Kenya") = "Nairobi" ' add or replace
capitals.Add("Peru", "Lima") ' add (throws if the key exists)
Console.WriteLine(capitals("Japan"))
Console.WriteLine(capitals.ContainsKey("Chile"))
Dim city As String = Nothing
If capitals.TryGetValue("Peru", city) Then Console.WriteLine($"Peru -> {city}")
capitals.Remove("France")
For Each pair In capitals
Console.WriteLine($"{pair.Key}: {pair.Value}")
Next
End Sub
End Module
Tokyo
False
Peru -> Lima
Japan: Tokyo
Kenya: Nairobi
Peru: Lima
Reading a missing key with capitals("Chile") throws a
KeyNotFoundException; TryGetValue is the safe way.
Counting with a dictionary
Module Program
Sub Main()
Dim counts As New Dictionary(Of String, Integer)
For Each word In "to be or not to be".Split(" "c)
If counts.ContainsKey(word) Then
counts(word) += 1
Else
counts(word) = 1
End If
Next
For Each pair In counts
Console.WriteLine($"{pair.Key} = {pair.Value}")
Next
End Sub
End Module
to = 2
be = 2
or = 1
not = 1
Other collections
| Collection | Use for |
|---|---|
HashSet(Of T) |
unique items, fast "contains" checks |
Queue(Of T) |
first in, first out (Enqueue, Dequeue) |
Stack(Of T) |
last in, first out (Push, Pop) |
SortedDictionary(Of K, V) |
a dictionary kept in key order |
Module Program
Sub Main()
Dim seen As New HashSet(Of Integer)
Console.WriteLine(seen.Add(5))
Console.WriteLine(seen.Add(5))
Dim line As New Queue(Of String)
line.Enqueue("first")
line.Enqueue("second")
Console.WriteLine(line.Dequeue())
Dim undo As New Stack(Of String)
undo.Push("typed a")
undo.Push("typed b")
Console.WriteLine(undo.Pop())
End Sub
End Module
True
False
first
typed b
Older code uses the non-generic ArrayList, Hashtable, and VB6's
Collection object, which store Objects and need casting. Prefer the
generic types.
Practice
Store product names and prices in a Dictionary(Of String, Decimal),
then print every product under 5 and the total price of all products.
Show solution
Module Program
Sub Main()
Dim prices As New Dictionary(Of String, Decimal) From {
{"Tea", 3.5D}, {"Cake", 6D}, {"Coffee", 4.25D}
}
Dim total = 0D
For Each pair In prices
If pair.Value < 5D Then Console.WriteLine($"{pair.Key}: {pair.Value}")
total += pair.Value
Next
Console.WriteLine($"Total: {total}")
End Sub
End Module
Tea: 3.5
Coffee: 4.25
Total: 13.75