Visual Basic 中的集合
在本章中,我们将处理 Visual Basic 集合。 .NET 框架为数据存储和检索提供了专门的类。 在上一章中,我们描述了数组。 集合是对数组的增强。
在 Visual Basic 中,有两种不同的集合类型。 标准集合位于System.Collections
命名空间下,而泛型集合位于System.Collections.Generic
下。 泛型集合更灵活,是处理数据的首选方式。 .NET Framework 2.0 中引入了泛型集合或泛型。 泛型可增强代码重用性,类型安全性和性能。
泛型编程是一种计算机编程样式,其中,算法根据待指定的后来的类型编写,然后在需要作为参数提供的特定类型时实例化。 这种方法由 Ada 于 1983 年率先提出,它允许编写仅在使用时所使用的类型集不同的常见功能或类型,从而减少了重复。 (维基百科)
ArrayList
ArrayList
是来自标准System.Collections
命名空间的集合。 它是一个动态数组。 它提供对元素的随机访问。 ArrayList
随着添加数据而自动扩展。 与数组不同,ArrayList
可以保存多种数据类型的数据。 ArrayList
中的元素通过整数索引访问。 索引从零开始。 元素的索引以及在ArrayList
末尾的插入和删除需要固定的时间。 在动态数组的中间插入或删除元素的成本更高。 这需要线性时间。
Option Strict On
Imports System.Collections
Module Example
Class Empty
End Class
Sub Main()
Dim da As ArrayList = New ArrayList()
da.Add("Visual Basic")
da.Add(344)
da.Add(55)
da.Add(New Empty)
da.Remove(55)
For Each el As Object In da
Console.WriteLine(el)
Next
End Sub
End Module
在上面的示例中,我们创建了一个ArrayList
集合。 我们添加了一些元素。 它们具有各种数据类型:一个字符串,两个整数和一个类对象。
Imports System.Collections
为了使用ArrayList
集合,我们需要导入System.Collections
命名空间。
Dim da As ArrayList = New ArrayList()
ArrayList
集合已创建。
da.Add("Visual Basic")
da.Add(344)
da.Add(55)
da.Add(New Empty)
我们使用Add()
方法将五个元素添加到数组中。
da.Remove(55)
我们删除一个元素。
For Each el As Object In da
Console.WriteLine(el)
Next
我们遍历数组并将其元素打印到控制台。
List
List
是可以通过索引访问的对象的强类型列表。 可以在System.Collections.Generic
命名空间下找到。
Option Strict On
Imports System.Collections.Generic
Module Example
Sub Main()
Dim langs As New List(Of String)
langs.Add("Java")
langs.Add("C#")
langs.Add("C")
langs.Add("C++")
langs.Add("Ruby")
langs.Add("Javascript")
Console.WriteLine(langs.Contains("C#"))
Console.WriteLine(langs(1))
Console.WriteLine(langs(2))
langs.Remove("C#")
langs.Remove("C")
Console.WriteLine(langs.Contains("C#"))
langs.Insert(4, "Haskell")
langs.Sort()
For Each lang As String In langs
Console.WriteLine(lang)
Next
End Sub
End Module
在前面的示例中,我们使用List
集合。
Imports System.Collections.Generic
为了使用List
集合,我们需要导入System.Collections.Generic
命名空间。
Dim langs As New List(Of String)
将创建一个通用动态数组。 我们指定将使用带有Of
关键字的字符串。
langs.Add("Java")
langs.Add("C#")
langs.Add("C")
...
我们使用Add()
方法将元素添加到列表中。
Console.WriteLine(langs.Contains("C#"))
我们使用Contains()
方法检查列表是否包含特定的字符串。
Console.WriteLine(langs(1))
Console.WriteLine(langs(2))
我们使用索引符号访问List
的第二个和第三个元素。
langs.Remove("C#")
langs.Remove("C")
我们从列表中删除两个字符串。
langs.Insert(4, "Haskell")
我们在特定位置插入一个字符串。
langs.Sort()
我们使用Sort()
方法对元素进行排序。
$ ./list.exe
True
C#
C
False
C++
Haskell
Java
Javascript
Ruby
示例的结果。
LinkedList
LinkedList
是 Visual Basic 中的通用双链表。 LinkedList
仅允许顺序访问。 LinkedList
允许进行固定时间的插入或删除,但只允许顺序访问元素。 由于链表需要额外的存储空间以供参考,因此对于诸如字符之类的小型数据项列表来说,它们是不切实际的。 与动态数组不同,可以将任意数量的项目添加到链表(当然受内存限制)而无需重新分配,这是一项昂贵的操作。
Option Strict On
Imports System.Collections.Generic
Module Example
Sub Main()
Dim nums As New LinkedList(Of Integer)
nums.AddLast(23)
nums.AddLast(34)
nums.AddLast(33)
nums.AddLast(11)
nums.AddLast(6)
nums.AddFirst(9)
nums.AddFirst(7)
Dim node as LinkedListNode(Of Integer)
node = nums.Find(6)
nums.AddBefore(node, 5)
For Each num As Integer In nums
Console.WriteLine(num)
Next
End Sub
End Module
这是一个LinkedList
示例,其中包含一些方法。
Dim nums As New LinkedList(Of Integer)
这是一个整数LinkedList
。
nums.AddLast(23)
...
nums.AddFirst(9)
我们使用AddLast()
和AddFirst()
方法填充链表。
Dim node as LinkedListNode(Of Integer)
node = nums.Find(6)
nums.AddBefore(node, 5)
LinkedList
由节点组成。 我们找到一个特定的节点,并在其之前添加一个元素。
For Each num As Integer In nums
Console.WriteLine(num)
Next
将所有元素打印到控制台。
Dictionary
dictionary
,也称为关联数组,是唯一键和值的集合,其中每个键与一个值相关联。 检索和添加值非常快。 字典占用更多内存,因为每个值都有一个键。
Option Strict On
Imports System.Collections.Generic
Module Example
Sub Main()
Dim domains As New Dictionary(Of String, String)
domains.Add("de", "Germany")
domains.Add("sk", "Slovakia")
domains.Add("us", "United States")
domains.Add("ru", "Russia")
domains.Add("hu", "Hungary")
domains.Add("pl", "Poland")
Console.WriteLine(domains("sk"))
Console.WriteLine(domains("de"))
Console.WriteLine("Dictionary has {0} items", _
domains.Count)
Console.WriteLine("Keys of the dictionary:")
Dim keys As Dictionary(Of String, String).KeyCollection = domains.Keys
For Each key As String In keys
Console.WriteLine("{0}", key)
Next
Console.WriteLine("Values of the dictionary:")
Dim vals As Dictionary(Of String, String).ValueCollection = domains.Values
For Each val As String In vals
Console.WriteLine("{0}", val)
Next
Console.WriteLine("Keys and values of the dictionary:")
For Each kvp As KeyValuePair(Of String, String) In domains
Console.WriteLine("Key = {0}, Value = {1}", _
kvp.Key, kvp.Value)
Next
End Sub
End Module
我们有一本字典,我们在其中将域名映射到其国家名称。
Dim domains As New Dictionary(Of String, String)
我们创建一个包含字符串键和值的字典。
domains.Add("de", "Germany")
domains.Add("sk", "Slovakia")
domains.Add("us", "United States")
...
我们将一些数据添加到字典中。 第一个字符串是键。 第二是值。
Console.WriteLine(domains("sk"))
Console.WriteLine(domains("de"))
在这里,我们通过它们的键检索两个值。
Console.WriteLine("Dictionary has {0} items", _
domains.Count)
我们通过引用Count
属性来打印项目数。
Dim keys As Dictionary(Of String, String).KeyCollection = domains.Keys
For Each key As String In keys
Console.WriteLine("{0}", key)
Next
这些行从字典中检索所有键。
Dim vals As Dictionary(Of String, String).ValueCollection = domains.Values
For Each val As String In vals
Console.WriteLine("{0}", val)
Next
这些行从字典中检索所有值。
For Each kvp As KeyValuePair(Of String, String) In domains
Console.WriteLine("Key = {0}, Value = {1}", _
kvp.Key, kvp.Value)
Next
最后,我们同时打印字典的键和值。
./dictionary.exe
Slovakia
Germany
Dictionary has 6 items
Keys of the dictionary:
de
sk
us
ru
hu
pl
Values of the dictionary:
Germany
Slovakia
United States
Russia
Hungary
Poland
Keys and values of the dictionary:
Key = de, Value = Germany
Key = sk, Value = Slovakia
Key = us, Value = United States
Key = ru, Value = Russia
Key = hu, Value = Hungary
Key = pl, Value = Poland
这是示例的输出。
queue
queue
是先进先出(FIFO)数据结构。 添加到队列中的第一个元素将是第一个要删除的元素。 队列可以用于处理消息出现时的消息,也可以用于消息到达时为客户服务的消息。 首先服务的是第一个客户。
Option Strict On
Imports System.Collections.Generic
Module Example
Sub Main()
Dim msgs As New Queue(Of String)
msgs.Enqueue("Message 1")
msgs.Enqueue("Message 2")
msgs.Enqueue("Message 3")
msgs.Enqueue("Message 4")
msgs.Enqueue("Message 5")
Console.WriteLine(msgs.Dequeue())
Console.WriteLine(msgs.Peek())
Console.WriteLine(msgs.Peek())
Console.WriteLine()
For Each msg As String In msgs
Console.WriteLine(msg)
Next
End Sub
End Module
在我们的示例中,我们有一个包含消息的队列。
Dim msgs As New Queue(Of String)
创建字符串队列。
msgs.Enqueue("Message 1")
msgs.Enqueue("Message 2")
...
Enqueue()
将消息添加到队列末尾。
Console.WriteLine(msgs.Dequeue())
Dequeue()
方法删除并返回队列开头的项目。
Console.WriteLine(msgs.Peek())
Peek()
方法从队列中返回下一项,但不会将其从集合中删除。
$ ./queue.exe
Message 1
Message 2
Message 2
Message 2
Message 3
Message 4
Message 5
Dequeue()
方法从集合中删除Message 1
。 Peek()
方法没有。 Message 2
保留在集合中。
stack
stack
是后进先出(LIFO)数据结构。 添加到队列中的最后一个元素将是第一个要删除的元素。 C 语言使用栈将本地数据存储在函数中。 实现计算器时,还将使用该栈。
Option Strict On
Imports System.Collections.Generic
Module Example
Sub Main()
Dim stc As New Stack(Of Integer)
stc.Push(1)
stc.Push(4)
stc.Push(3)
stc.Push(6)
stc.Push(4)
Console.WriteLine(stc.Pop())
Console.WriteLine(stc.Peek())
Console.WriteLine(stc.Peek())
Console.WriteLine()
For Each item As Integer In stc
Console.WriteLine(item)
Next
End Sub
End Module
上面有一个简单的栈示例。
Dim stc As New Stack(Of Integer)
创建一个Stack
数据结构。
stc.Push(1)
stc.Push(4)
...
Push()
方法将一个项目添加到栈的顶部。
Console.WriteLine(stc.Pop())
Pop()
方法从栈顶部删除并返回该项目。
Console.WriteLine(stc.Peek())
Peek()
方法从栈顶部返回该项目。 它不会删除它。
$ ./stack.exe
4
6
6
6
3
4
1
输出。
Visual Basic 教程的这一部分专用于 Visual Basic 中的集合。