C# 集合(Collection)
集合(Collection)类是专门用于数据存储和检索的类。这些类提供了对栈(stack)、队列(queue)、列表(list)和哈希表(hash table)的支持。大多数集合类实现了相同的接口。
集合(Collection)类服务于不同的目的,如为元素动态分配内存,基于索引访问列表项等等。这些类创建 Object 类的对象的集合。在 C# 中,Object 类是所有数据类型的基类。
动态数组(ArrayList)
它代表了可被单独索引的对象的有序集合。
它基本上可以替代一个数组。但是,与数组不同的是,您可以使用索引在指定的位置添加和移除项目,动态数组会自动重新调整它的大小。它也允许在列表中进行动态内存分配、增加、搜索、排序各项。
基本结构
1
public class ArrayList : ICollection, IEnumerable, IList, ICloneable
实现接口:
IList:支持按索引访问元素。
ICollection:支持集合基本操作,如添加、删除和计数。
IEnumerable:支持通过枚举器遍历元素。
ICloneable:支持克隆 ArrayList。
特点
动态扩展
ArrayList 的容量可以根据需要自动调整,不需要指定固定大小。
当添加的元素超过当前容量时,ArrayList 会自动增加容量(通常是原容量的两倍)。
非泛型集合
- ArrayList 是非泛型集合,所有元素被存储为 object 类型。这意味着它可以存储任意类型的对象,但需要注意装箱(boxing)和拆箱(unboxing)的性能影响。
无序操作
- 虽然元素存储顺序与添加顺序一致,但它并不提供内置排序功能。
线程安全
- 默认不是线程安全的。如果需要线程安全的 ArrayList,可以使用 ArrayList.Synchronized 方法生成一个线程安全的版本。
ArrayList 类的方法和属性
下表列出了 ArrayList 类的一些常用的 属性:
属性名称 类型 描述
Count int 获取 ArrayList 中包含的元素数量。
Capacity int 获取或设置 ArrayList 的容量(存储空间)。
IsFixedSize bool 指示 ArrayList 是否具有固定大小。
IsReadOnly bool 指示 ArrayList 是否为只读。
IsSynchronized bool 指示 ArrayList 是否线程安全。
SyncRoot object 获取可用于同步访问的对象。
下表列出了 ArrayList 类的一些常用的 方法:
方法名称 返回类型 描述
添加与插入
Add(object value) int 将对象添加到 ArrayList 的末尾,返回新元素的索引。
AddRange(ICollection c) void 将指定集合的所有元素添加到 ArrayList 的末尾。
Insert(int index, object value) void 在指定索引处插入对象。
InsertRange(int index, ICollection c) void 在指定索引处插入指定集合的所有元素。
删除
Remove(object value) void 移除首次出现的指定对象。
RemoveAt(int index) void 移除指定索引处的元素。
RemoveRange(int index, int count) void 移除从指定索引开始的指定数量的元素。
Clear() void 移除所有元素。
访问与查询
Contains(object item) bool 判断 ArrayList 是否包含指定对象。
IndexOf(object value) int 获取指定对象首次出现的索引。
LastIndexOf(object value) int 获取指定对象最后一次出现的索引。
排序与复制
Sort() void 按照默认顺序排序 ArrayList 中的元素。
Sort(IComparer comparer) void 按照自定义比较器排序。
Reverse() void 反转 ArrayList 中元素的顺序。
CopyTo(Array array) void 将 ArrayList 的元素复制到指定数组中。
其他
GetRange(int index, int count) ArrayList 获取从指定索引开始的指定数量的元素子集。
ToArray() object[] 将 ArrayList 中的元素复制到数组中。
TrimToSize() void 将容量调整为实际元素数量以节省内存。
> 实例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
using System;
using System.Collections;
namespace CollectionApplication
{
class Program
{
static void Main(string[] args)
{
// 创建动态数组并初始化
ArrayList numbers = InitializeArrayList();
// 显示数组的容量和元素个数
DisplayArrayListInfo(numbers);
// 显示数组内容
Console.Write("Original Content: ");
DisplayArrayListContent(numbers);
// 对数组内容排序
numbers.Sort();
// 显示排序后的内容
Console.Write("Sorted Content: ");
DisplayArrayListContent(numbers);
Console.ReadKey(); // 等待用户按键退出
}
/// <summary>
/// 初始化并填充 ArrayList
/// </summary>
/// <returns>包含初始数据的 ArrayList</returns>
static ArrayList InitializeArrayList()
{
ArrayList al = new ArrayList();
Console.WriteLine("Adding numbers to the ArrayList:");
// 添加初始元素
int[] initialNumbers = { 45, 78, 33, 56, 12, 23, 9 };
foreach (int num in initialNumbers)
{
al.Add(num);
Console.WriteLine($"Added: {num}");
}
return al;
}
/// <summary>
/// 显示 ArrayList 的容量和元素个数
/// </summary>
/// <param name="al">ArrayList 对象</param>
static void DisplayArrayListInfo(ArrayList al)
{
Console.WriteLine($"\nCapacity: {al.Capacity}"); // 当前容量
Console.WriteLine($"Count: {al.Count}"); // 当前元素个数
}
/// <summary>
/// 显示 ArrayList 的内容
/// </summary>
/// <param name="al">ArrayList 对象</param>
static void DisplayArrayListContent(ArrayList al)
{
foreach (int num in al)
{
Console.Write(num + " ");
}
Console.WriteLine(); // 换行
}
}
}
当上面的代码被编译和执行时,它会产生下列结果:
1
2
3
4
5
6
7
8
9
10
11
12
13
Adding numbers to the ArrayList:
Added: 45
Added: 78
Added: 33
Added: 56
Added: 12
Added: 23
Added: 9
Capacity: 16
Count: 7
Original Content: 45 78 33 56 12 23 9
Sorted Content: 9 12 23 33 45 56 78
与泛型集合 List
特性 ArrayList List<T>
类型安全 否(存储 object 类型) 是(泛型,强类型约束)
装箱与拆箱 是(值类型需要) 否
性能 较低 较高
泛型支持 无 有
使用场景 遗留代码或简单场景 现代开发中优先选择
注意事项
避免频繁装箱和拆箱:
如果数据主要是值类型,建议使用 List
来避免性能开销。 慎用混合类型数据:
尽量不要混合存储不同类型的对象,以降低运行时错误的风险。
替代方案:
在现代 C# 开发中,推荐使用泛型集合(如 List
、Dictionary<TKey, TValue>)以提高代码的安全性和效率。
哈希表(Hashtable)
它使用键来访问集合中的元素。
当您使用键访问元素时,则使用哈希表,而且您可以识别一个有用的键值。哈希表中的每一项都有一个键/值对。键用于访问集合中的项目。
在 C# 中,哈希表(Hashtable) 是一种以键值对(key=>value)形式存储数据的集合,键和值可以是任意对象。
哈希表中的每一项都有一个key=>value对,key 用于访问集合中的项目。
哈希表基于哈希算法组织和访问数据,提供高效的查找、插入和删除操作。
Hashtable 是非泛型集合,位于命名空间 System.Collections 中。如果需要泛型版本,可以使用 Dictionary<TKey, TValue>。
基本结构
键(Key):用于标识每个数据项,必须是唯一的,不能为 null。
值(Value):键所对应的数据,可以为 null。
特点
键值对存储:每个键都是唯一的,与一个值相关联。
哈希算法:通过键的哈希码定位数据存储位置,查找和插入操作的平均时间复杂度为 O(1)。
动态调整容量:当哈希表中元素数目超过容量时,表会动态扩展并重新分配存储。
无序存储:键值对的存储顺序与插入顺序无关,由哈希码决定。
Hashtable 类的方法和属性
下表列出了 Hashtable 类的一些常用的 属性:
属性名称 类型 描述
Count int 获取哈希表中包含的键值对数量。
IsReadOnly bool 指示哈希表是否为只读。
IsFixedSize bool 指示哈希表是否具有固定大小。
IsSynchronized bool 指示哈希表是否线程安全。
Keys ICollection 获取哈希表中所有键的集合。
Values ICollection 获取哈希表中所有值的集合。
SyncRoot object 获取可用于同步访问哈希表的对象。
下表列出了 Hashtable 类的一些常用的 方法:
方法名称 返回类型 描述
添加与删除
Add(object key, object value) void 将指定的键值对添加到哈希表。
Clear() void 清空哈希表。
Remove(object key) void 删除指定键的键值对。
查询与访问
Contains(object key) bool 判断哈希表中是否包含指定键。
ContainsKey(object key) bool 判断哈希表中是否包含指定键(等效于 Contains)。
ContainsValue(object value) bool 判断哈希表中是否包含指定值。
复制与枚举
CopyTo(Array array, int index) void 将哈希表的元素复制到数组,从指定索引处开始。
GetEnumerator() IDictionaryEnumerator 返回哈希表的枚举器,用于遍历键值对。
> 实例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
using System;
using System.Collections;
namespace CollectionsApplication
{
class Program
{
static void Main(string[] args)
{
Hashtable ht = new Hashtable();
ht.Add("001", "Zara Ali");
ht.Add("002", "Abida Rehman");
ht.Add("003", "Joe Holzner");
ht.Add("004", "Mausam Benazir Nur");
ht.Add("005", "M. Amlan");
ht.Add("006", "M. Arif");
ht.Add("007", "Ritesh Saikia");
if (ht.ContainsValue("Nuha Ali"))
{
Console.WriteLine("This student name is already in the list");
}
else
{
ht.Add("008", "Nuha Ali");
}
// 获取键的集合
ICollection key = ht.Keys;
foreach (string k in key)
{
Console.WriteLine(k + ": " + ht[k]);
}
Console.ReadKey();
}
}
}
当上面的代码被编译和执行时,它会产生下列结果:
1
2
3
4
5
6
7
8
007: Ritesh Saikia
004: Mausam Benazir Nur
005: M. Amlan
008: Nuha Ali
002: Abida Rehman
003: Joe Holzner
001: Zara Ali
006: M. Arif
与其他集合的对比
特性 Hashtable Dictionary<TKey, TValue>
类型安全 否(非泛型,存储 object 类型) 是(泛型,强类型约束)
性能 较慢(需进行装箱和拆箱操作) 更快(无装箱操作,泛型直接支持类型)
键的唯一性 是 是
值是否可为 null 是 是
排序 无 无
线程安全 默认非线程安全 默认非线程安全
Hashtable 是一种高效的键值对集合,适用于需要快速存储和检索键值对的场景。
非泛型 的设计使其在类型安全和性能方面逊色于泛型版本的集合(如 Dictionary<TKey, TValue>)。
在现代 C# 开发中,Dictionary<TKey, TValue> 更常被使用,但 Hashtable 仍然适合简单应用或与遗留代码兼容的场景。
排序列表(SortedList)
它可以使用键和索引来访问列表中的项。
排序列表是数组和哈希表的组合。它包含一个可使用键或索引访问各项的列表。如果您使用索引访问各项,则它是一个动态数组(ArrayList),如果您使用键访问各项,则它是一个哈希表(Hashtable)。集合中的各项总是按键值排序。
在 C# 中,排序列表(SortedList) 是一种按键自动排序的集合,它通过键值对存储数据,并在添加或更新时根据键的顺序(升序)自动排序。
SortedList 类代表了一系列按照键来排序的 key => value 对,这些键值对可以通过键和索引来访问。
排序列表是数组和哈希表的组合。它包含一个可使用键或索引访问各项的列表。如果您使用索引访问各项,则它是一个动态数组(ArrayList),如果您使用键访问各项,则它是一个哈希表(Hashtable)。集合中的各项总是按键值排序。
SortedList 两种版本
非泛型 SortedList(System.Collections.SortedList)
泛型 SortedList<TKey, TValue>(System.Collections.Generic.SortedList<TKey, TValue>)
特点:
自动排序:所有键都按照升序排序,无需手动调用排序方法。
键值对存储:每个键都唯一,与其关联的值可以重复。
动态调整容量:根据需要自动调整内部存储的大小。
索引访问:通过键或索引访问数据。
高效操作:检索、插入、删除的平均时间复杂度为 O(log n)。
SortedList 类的方法和属性
下表列出了 SortedList 类的一些常用的 属性:
属性名称 类型 描述
Count int 获取排序列表中键值对的数量。
Capacity int 获取或设置排序列表的容量。
Comparer IComparer 或 IComparer<TKey> 获取用于对键进行排序的比较器。
IsReadOnly bool 指示排序列表是否为只读。
IsFixedSize bool 指示排序列表是否具有固定大小(始终为 false)。
Keys ICollection 或 IList<TKey> 获取排序列表中的所有键。
Values ICollection 或 IList<TValue> 获取排序列表中的所有值。
下表列出了 SortedList 类的一些常用的 方法:
方法名称 返回类型 描述
添加与移除
Add(TKey key, TValue value) void 将指定的键值对添加到排序列表。
Remove(TKey key) bool 从排序列表中移除具有指定键的元素。
RemoveAt(int index) void 移除排序列表中指定索引位置的键值对。
Clear() void 移除排序列表中的所有元素。
查找与访问
ContainsKey(TKey key) bool 确定排序列表是否包含指定的键。
ContainsValue(TValue value) bool 确定排序列表是否包含指定的值。
IndexOfKey(TKey key) int 返回指定键的索引。
IndexOfValue(TValue value) int 返回指定值的索引。
TryGetValue(TKey key, out TValue value) bool 获取与指定键相关联的值,如果存在则返回 true。
复制与枚举
CopyTo(Array array, int index) void 将排序列表中的元素复制到数组,从指定索引开始。
GetEnumerator() IEnumerator 返回一个枚举器,用于循环访问排序列表中的元素。
非泛型版操作:
> 实例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
using System;
using System.Collections;
namespace CollectionsApplication
{
class Program
{
static void Main(string[] args)
{
SortedList sl = new SortedList();
sl.Add("001", "Zara Ali");
sl.Add("002", "Abida Rehman");
sl.Add("003", "Joe Holzner");
sl.Add("004", "Mausam Benazir Nur");
sl.Add("005", "M. Amlan");
sl.Add("006", "M. Arif");
sl.Add("007", "Ritesh Saikia");
if (sl.ContainsValue("Nuha Ali"))
{
Console.WriteLine("This student name is already in the list");
}
else
{
sl.Add("008", "Nuha Ali");
}
// 获取键的集合
ICollection key = sl.Keys;
foreach (string k in key)
{
Console.WriteLine(k + ": " + sl[k]);
}
}
}
}
当上面的代码被编译和执行时,它会产生下列结果:
1
2
3
4
5
6
7
8
001: Zara Ali
002: Abida Rehman
003: Joe Holzner
004: Mausam Banazir Nur
005: M. Amlan
006: M. Arif
007: Ritesh Saikia
008: Nuha Ali
泛型版:
> 实例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
// 创建泛型 SortedList
SortedList<int, string> sortedList = new SortedList<int, string>();
// 添加键值对
sortedList.Add(2, "Banana");
sortedList.Add(1, "Apple");
sortedList.Add(3, "Cherry");
// 自动按键排序
Console.WriteLine("SortedList contents:");
foreach (var kvp in sortedList)
{
Console.WriteLine($"Key: {kvp.Key}, Value: {kvp.Value}");
}
// 查找与访问
Console.WriteLine($"\nValue for key 2: {sortedList[2]}"); // 输出:Banana
// 删除元素
sortedList.Remove(1);
Console.WriteLine("\nAfter removing key 1:");
foreach (var kvp in sortedList)
{
Console.WriteLine($"Key: {kvp.Key}, Value: {kvp.Value}");
}
// 检查键与值
Console.WriteLine($"\nContains key 3: {sortedList.ContainsKey(3)}"); // 输出:True
Console.WriteLine($"Contains value 'Apple': {sortedList.ContainsValue("Apple")}"); // 输出:False
}
}
堆栈(Stack)
它代表了一个后进先出的对象集合。
当您需要对各项进行后进先出的访问时,则使用堆栈。当您在列表中添加一项,称为推入元素,当您从列表中移除一项时,称为弹出元素。
在 C# 中,堆栈(Stack) 是一种后进先出(LIFO, Last In First Out)的数据结构。
堆栈(Stack)适用于存储和按顺序处理数据,其中最新添加的元素会最先被移除。
堆栈(Stack)代表了一个后进先出的对象集合。当您需要对各项进行后进先出的访问时,则使用堆栈。当您在列表中添加一项,称为推入元素,当您从列表中移除一项时,称为弹出元素。
Stack 提供了两种实现方式:
非泛型 Stack(System.Collections.Stack):支持存储任何类型的对象(需要装箱和拆箱操作)。
泛型 Stack
(System.Collections.Generic.Stack ):支持强类型对象,避免装箱和拆箱,提高性能。
Stack 特性:
后进先出:最后压入堆栈的元素最先弹出。
动态大小:堆栈的容量根据需要动态调整。
泛型支持:通过 Stack
提供类型安全,避免类型转换错误。 非线程安全:默认 Stack 和 Stack
都不是线程安全的。
Stack 类的方法和属性
下表列出了 Stack 类的一些常用的 属性:
属性名称 类型 描述
Count int 获取堆栈中的元素个数。
SyncRoot object 获取一个对象,用于同步对堆栈的访问(非泛型)。
IsSynchronized bool 指示堆栈的访问是否同步(线程安全,始终为 false)。
td>获取 Stack 中包含的元素个数。
下表列出了 Stack 类的一些常用的 方法:
方法名称 返回类型 描述
元素操作
Push(object item) void 将元素压入堆栈的顶部。
Pop() object 移除并返回堆栈顶部的元素。
Peek() object 返回堆栈顶部的元素,但不移除。
Clear() void 移除堆栈中的所有元素。
检查与复制
Contains(object item) bool 确定某元素是否存在于堆栈中。
ToArray() object[] 将堆栈中的元素复制到新数组中(顺序翻转)。
Clone() object 创建当前堆栈的浅表副本。
CopyTo(Array array, int index) void 将堆栈中的元素复制到现有数组,从指定索引开始。
枚举器支持
GetEnumerator() IEnumerator 返回一个枚举器,用于循环访问堆栈中的元素。
线程安全
Synchronized(Stack stack) Stack 返回一个线程安全的堆栈包装器。
下面的实例演示了堆栈(Stack)的使用。
非泛型堆栈:
> 实例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
using System;
using System.Collections;
namespace CollectionsApplication
{
class Program
{
static void Main(string[] args)
{
Stack st = new Stack();
st.Push('A');
st.Push('M');
st.Push('G');
st.Push('W');
Console.WriteLine("Current stack: ");
foreach (char c in st)
{
Console.Write(c + " ");
}
Console.WriteLine();
st.Push('V');
st.Push('H');
Console.WriteLine("The next poppable value in stack: {0}",
st.Peek());
Console.WriteLine("Current stack: ");
foreach (char c in st)
{
Console.Write(c + " ");
}
Console.WriteLine();
Console.WriteLine("Removing values ");
st.Pop();
st.Pop();
st.Pop();
Console.WriteLine("Current stack: ");
foreach (char c in st)
{
Console.Write(c + " ");
}
}
}
}
当上面的代码被编译和执行时,它会产生下列结果:
1
2
3
4
5
6
7
8
Current stack:
W G M A
The next poppable value in stack: H
Current stack:
H V W G M A
Removing values
Current stack:
G M A
泛型堆栈:
> 实例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
Stack<int> stack = new Stack<int>();
// 压栈
stack.Push(10);
stack.Push(20);
stack.Push(30);
// 查看堆栈顶部
Console.WriteLine($"Peek: {stack.Peek()}"); // 输出:30
// 弹栈
Console.WriteLine($"Pop: {stack.Pop()}"); // 输出:30
// 剩余堆栈
Console.WriteLine("Remaining items:");
foreach (var item in stack)
{
Console.WriteLine(item); // 输出:20, 10
}
}
}
Stack 与 Stack 区别
Stack(非泛型)
存储对象为 object 类型。
使用时需要显式类型转换,可能会导致运行时异常。Stack
(泛型)
提供类型安全,避免类型转换问题。
性能更优,因为避免了装箱和拆箱的开销。
队列(Queue)
它代表了一个先进先出的对象集合。
当您需要对各项进行先进先出的访问时,则使用队列。当您在列表中添加一项,称为入队,当您从列表中移除一项时,称为出队。
在 C# 中,Queue 是一个先进先出(FIFO, First In First Out)数据结构。
Queue 属于 System.Collections 或 System.Collections.Generic 命名空间,分别提供非泛型和泛型版本的实现。Queue 适用于需要按照入队顺序处理数据的场景。
队列(Queue)代表了一个先进先出的对象集合。当您需要对各项进行先进先出的访问时,则使用队列。当您在列表中添加一项,称为入队,当您从列表中移除一项时,称为出队。
特性
先进先出:最早加入队列的元素最先被移除。
动态大小:队列的容量会根据需要动态调整。
泛型支持:通过 Queue
可以存储强类型的元素。 线程安全:Queue 本身不是线程安全的,但可以使用 ConcurrentQueue
实现线程安全。
Queue 类的方法和属性
下表列出了 Queue 类的一些常用的 属性:
属性名称 类型 描述
Count int 获取队列中的元素个数。
SyncRoot object 获取一个对象,用于同步对队列的访问(非泛型)。
IsSynchronized bool 指示队列的访问是否同步(线程安全,始终为 false)。
下表列出了 Queue 类的一些常用的 方法:
方法名称 返回类型 描述
元素操作
Enqueue(object item) void 将元素添加到队列的末尾。
Dequeue() object 移除并返回队列开头的元素。
Peek() object 返回队列开头的元素,但不移除。
Clear() void 移除队列中的所有元素。
检查与复制
Contains(object item) bool 确定某元素是否存在于队列中。
ToArray() object[] 将队列中的元素复制到新数组中。
Clone() object 创建当前队列的浅表副本。
CopyTo(Array array, int index) void 将队列中的元素复制到现有数组,从指定索引开始。
枚举器支持
GetEnumerator() IEnumerator 返回一个枚举器,用于循环访问队列中的元素。
线程安全
Synchronized(Queue queue) Queue 返回一个线程安全的队列包装器。
下面的实例演示了队列(Queue)的使用:
> 实例1:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
using System;
using System.Collections;
class Program
{
static void Main()
{
Queue queue = new Queue();
// 添加元素
queue.Enqueue("First");
queue.Enqueue("Second");
queue.Enqueue("Third");
// 查看队首
Console.WriteLine($"Peek: {queue.Peek()}"); // 输出:First
// 移除元素
Console.WriteLine($"Dequeue: {queue.Dequeue()}"); // 输出:First
// 剩余元素
foreach (var item in queue)
{
Console.WriteLine(item); // 输出:Second, Third
}
// 检查包含
Console.WriteLine($"Contains 'Second': {queue.Contains("Second")}"); // 输出:True
// 转数组
object[] array = queue.ToArray();
Console.WriteLine($"Array Length: {array.Length}"); // 输出:2
}
}
> 实例2:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
using System;
using System.Collections;
namespace CollectionsApplication
{
class Program
{
static void Main(string[] args)
{
Queue q = new Queue();
q.Enqueue('A');
q.Enqueue('M');
q.Enqueue('G');
q.Enqueue('W');
Console.WriteLine("Current queue: ");
foreach (char c in q)
Console.Write(c + " ");
Console.WriteLine();
q.Enqueue('V');
q.Enqueue('H');
Console.WriteLine("Current queue: ");
foreach (char c in q)
Console.Write(c + " ");
Console.WriteLine();
Console.WriteLine("Removing some values ");
char ch = (char)q.Dequeue();
Console.WriteLine("The removed value: {0}", ch);
ch = (char)q.Dequeue();
Console.WriteLine("The removed value: {0}", ch);
Console.ReadKey();
}
}
}
当上面的代码被编译和执行时,它会产生下列结果:
1
2
3
4
5
6
7
Current queue:
A M G W
Current queue:
A M G W V H
Removing values
The removed value: A
The removed value: M
点阵列(BitArray)
它代表了一个使用值 1 和 0 来表示的二进制数组。
当您需要存储位,但是事先不知道位数时,则使用点阵列。您可以使用整型索引从点阵列集合中访问各项,索引从零开始。
BitArray 是 C# 中用于表示一组位(bit)值的集合。
BitArray 属于 System.Collections 命名空间,主要用于处理二进制数据或进行位操作,相比使用布尔数组(bool[]),BitArray 更加高效,因为它以紧凑的方式存储每个位。
BitArray 类管理一个紧凑型的位值数组,它使用布尔值来表示,其中 true 表示位是开启的(1),false 表示位是关闭的(0)。
当您需要存储位,但是事先不知道位数时,则使用点阵列。您可以使用整型索引从点阵列集合中访问各项,索引从零开始。
BitArray 类的方法和属性
下表列出了 BitArray 类的一些常用的 属性:
属性名称 类型 描述
Count int 获取 BitArray 中的位数(只读)。
Length int 获取或设置 BitArray 中的位数(支持动态调整大小)。
IsReadOnly bool 获取一个值,指示 BitArray 是否为只读(始终为 false)。
SyncRoot object 获取一个对象,用于同步对 BitArray 的访问。
IsSynchronized bool 获取一个值,指示对 BitArray 的访问是否同步(线程安全)。
Item[int index] bool 获取或设置指定索引处的位的值(通过索引器访问)。
属性访问:
BitArray bits = new BitArray(8);
Console.WriteLine(bits.Length); // 输出:8
bits.Length = 10; // 修改长度为 10
下表列出了 BitArray 类的一些常用的 方法:
方法名称 返回类型 描述
And(BitArray) BitArray 按位与操作,将两个 BitArray 对应位进行与运算,并返回结果。
Or(BitArray) BitArray 按位或操作,将两个 BitArray 对应位进行或运算,并返回结果。
Xor(BitArray) BitArray 按位异或操作,将两个 BitArray 对应位进行异或运算,并返回结果。
Not() BitArray 按位取反操作,将 BitArray 的每个位取反,并返回结果。
Set(int index, bool value) void 将指定索引处的位设置为指定值(true 或 false)。
SetAll(bool value) void 将所有位设置为指定值(true 或 false)。
Get(int index) bool 获取指定索引处的位的值。
Clone() object 创建当前 BitArray 的浅表副本(复制)。
CopyTo(Array array, int index) void 将 BitArray 的内容复制到指定的数组,从指定索引开始。
Equals(object obj) bool 确定指定对象是否等于当前 BitArray。
GetEnumerator() IEnumerator 返回一个枚举器,用于循环访问 BitArray 中的位。
方法使用:
BitArray bits = new BitArray(8, false); // 创建 8 位数组,全部为 false
bits.Set(0, true); // 设置第 0 位为 true
Console.WriteLine(bits.Get(0)); // 输出:True
bits.SetAll(true); // 全部设置为 true
实例
下面的实例演示了点阵列(BitArray)的使用:
> 实例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
using System;
using System.Collections;
namespace CollectionsApplication
{
class Program
{
static void Main(string[] args)
{
// 初始化两个 BitArray,用于存储二进制位
BitArray ba1 = new BitArray(new byte[] { 60 }); // 60 = 00111100
BitArray ba2 = new BitArray(new byte[] { 13 }); // 13 = 00001101
// 输出 ba1 和 ba2 的内容
Console.WriteLine("Bit array ba1 (60):");
PrintBitArray(ba1);
Console.WriteLine("Bit array ba2 (13):");
PrintBitArray(ba2);
// 进行 AND 操作并输出结果
BitArray baAnd = ba1.And(ba2); // 60 & 13 = 12
Console.WriteLine("Bit array after AND operation (12):");
PrintBitArray(baAnd);
// 进行 OR 操作并输出结果
BitArray baOr = ba1.Or(ba2); // 60 | 13 = 61
Console.WriteLine("Bit array after OR operation (61):");
PrintBitArray(baOr);
Console.ReadKey();
}
// 输出 BitArray 的值
static void PrintBitArray(BitArray bitArray)
{
foreach (bool bit in bitArray)
{
Console.Write($"{(bit ? 1 : 0)} ");
}
Console.WriteLine("\n");
}
}
}
当上面的代码被编译和执行时,它会产生下列结果:
1
2
3
4
5
6
7
8
9
10
11
Bit array ba1 (60):
0 0 1 1 1 1 0 0
Bit array ba2 (13):
1 1 0 1 0 0 0 0
Bit array after AND operation (12):
0 0 0 1 0 0 0 0
Bit array after OR operation (61):
1 1 1 1 1 1 0 0
List
构建List:
1
var list=new List<int>();
首先,List 是个强类型,很安全。其次看那个尖括号,它是 C#2.0 时加入的泛型,所以并不存在像 ArrayList。
那样要拆/装箱以此造成性能浪费。
然后,List 通过索引分配,索引与数组一样,从 0 开始。它可以通过索引来读取值:
1
2
3
4
var a=new List<int>();
a.Add(12);
a.Add(10);
Console.WriteLine(a[0]);
列表可以有相同的项,而且项是手动排序。
在改变项后,要注意项的索引会发生改变:
1
2
3
4
5
6
var a=new List<int>();
a.Add(12);
a.Add(10);
Console.WriteLine(a[0]);
a.Remove(12);
Console.WriteLine(a[0]);
提供一下常用的列表方法:
1、Add() 将东西加入到列表的最后。
2、Remove() 删掉项中第一个匹配你想删除的条件的项(删去第一个匹配此条件的项)。
3、Clear() 清空所有项。
4、Sort() 用系统默认的方式对项进行排序。
5、Contains() 查看某项是否存在于列表中。
> 实例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
using System;
using static System.Console;
using System.Collections.Generic;
namespace HelloWorldApplication
{
class HelloWorld
{
static void Main(string[] args)
{
var a=new List<int>();
a.Add(2);
a.Add(6);
a.Add(2);
a.Add(10);
Console.WriteLine($"第一个数为{a[0]}");
a.Remove(2);//删去第一个匹配此条件的项
a.Sort();
foreach(var a2 in a)
{
WriteLine(a2);
}
bool a3=a.Contains(2);
WriteLine(a3);
Console.ReadKey();
}
}
}