在C#中,集合类型主要分为几大类,包括数组、列表、栈、队列、链表等。每种集合类型都有不同的用途和特性。
数组(Array)
-
数组 (
Array
):一种固定大小的集合,可以存储相同类型的元素。支持索引访问。数组本身是引用类型-
多维数组
int[,] multiArray = new int[3, 4];
是一个二维数组。 -
交错数组:又称为锯齿数组,是数组的数组
int[][] jaggedArray = new int[3][];
-
多维数组
列表(List)
-
列表 (
List<T>
):一种动态数组,可以自动调整大小,常用的泛型集合类型。因为是动态数组,所以底层实现还是数组
链表(LinkedList)
-
双向链表 (
LinkedList<T>
):每个节点都包含一个值和指向前后两个节点的指针,适用于频繁插入/删除操作的场景。但是读取操作会比较慢
栈(Stack)
-
栈 (
Stack<T>
):后进先出(LIFO)的集合类型,元素只能从栈顶添加或移除。
队列(Queue)
-
队列 (
Queue<T>
):先进先出(FIFO)的集合类型,元素从队列尾部添加,从队列头部移除。
字典(Dictionary)
-
字典 (
Dictionary<TKey, TValue>
):一种键值对集合,通过键快速查找对应的值。
哈希集合(HashSet)
-
哈希集合 (
HashSet<T>
):一种无序集合,不允许重复元素,通常用于集合操作(如交集、并集)。
HashSet和Dictionary的插入可能不一定有List性能高,因为要计算哈希值,还要看原先有没有值,而List放在末尾就行,但是他们的Contains性能要远远好于List,复杂度O(1)
VS O(n)
所以当需要查询Contains的时候,优先考虑使用HashSet和Dictionary
有序集合(SortedSet)
-
有序集合 (
SortedSet<T>
):类似于HashSet
,但元素按排序顺序存储。
并发队列 阻塞集合
-
并发队列 (
ConcurrentQueue<T>
):线程安全的先进先出集合。 -
阻塞集合(
BlockingCollection<T>
):提供阻塞和限流功能的集合,通常用于生产者-消费者模式。
并发栈
-
并发栈 (
ConcurrentStack<T>
):线程安全的后进先出集合。
并发字典
-
并发字典 (
ConcurrentDictionary<TKey, TValue>
):线程安全的键值对集合,支持高效的并发操作。
HashSet没有并发的版本,不知道为啥把人家漏了,HashSet本身也不是线程安全的,所以如果需要用到HashSet的并发版本,可以用ConcurrentDictionary替代,值里面不放东西就行了,或者根据自己的业务逻辑加锁
自己加锁要小心处理,HashSet的问题比如两个线程同时插入同一条数据,检测时计算哈希值都是没有数据,两个线程插入后就出错了,或者删除也有类似的问题,但是不止是插入删除加锁就行,还涉及到HashSet的扩容问题,迭代器的线程安全问题等等,需要彻底了解HashSet的底层实现再处理
并发链表
-
并发链表 (
ConcurrentBag<T>
):线程安全的无序集合,适用于需要频繁插入和删除操作的场景。
Immutable Collections(不可变集合)
-
不可变集合 (
ImmutableList<T>
,ImmutableDictionary<TKey, TValue>
,ImmutableQueue<T>
,ImmutableStack<T>
,ImmutableHashSet<T>
等):一旦创建,集合内容无法更改,适用于并发场景下的安全读取操作。ImmutableList<int> immutableList = ImmutableList.Create(1, 2, 3);
特殊用途集合
-
队列字典 (
Queue<T>.Enumerator
):一种专门用于处理队列中元素的枚举类型。 -
栈字典 (
Stack<T>.Enumerator
):一种专门用于处理栈中元素的枚举类型。