Visual Basic 集合
最后修改于 2023 年 10 月 18 日
在本章中,我们将讨论 Visual Basic 集合。 .NET 框架提供了用于数据存储和检索的专用类。 在上一章中,我们描述了数组。 集合是数组的增强功能。
Visual Basic 中有两种不同的集合类型。 标准集合位于 System.Collections 命名空间下,泛型集合位于 System.Collections.Generic 下。 泛型集合更灵活,是处理数据的首选方式。 泛型集合或泛型是在 .NET 框架 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
方法向 List 添加元素。
Console.WriteLine(langs.Contains("C#"))
我们使用 Contains
方法检查 List 是否包含特定的字符串。
Console.WriteLine(langs(1)) Console.WriteLine(langs(2))
我们使用索引符号访问 List 的第二个和第三个元素。
langs.Remove("C#") langs.Remove("C")
我们从 List 中删除了两个字符串。
langs.Insert(4, "Haskell")
我们在特定位置插入了一个字符串。
langs.Sort()
我们使用 Sort
方法对元素进行排序。
$ dotnet run 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
字典
,也称为关联数组,是唯一键和值集合的集合,其中每个键都与一个值相关联。 检索和添加值非常快。 字典需要更多内存,因为对于每个值,也有一个键。
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
最后,我们打印字典的键和值。
$ dotnet run 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
队列
队列
是一种先入先出 (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
方法返回队列中的下一个项目,但不会将其从集合中删除。
$ dotnet run Message 1 Message 2 Message 2 Message 2 Message 3 Message 4 Message 5
Dequeue
方法从集合中删除“Message 1”。 Peek
方法不会。 “Message 2”保留在集合中。
栈
栈
是一种后进先出 (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
方法返回堆栈顶部的项目。 它不会将其删除。
$ dotnet run 4 6 6 6 3 4 1
Visual Basic 教程的这一部分专门介绍了 Visual Basic 中的集合。