C# 集合(Collection)详解以及区别

embedded/2025/3/22 9:16:46/

C# 集合(Collection)是用于数据存储和检索的核心数据结构,支持动态内存管理、多种数据组织形式及高效操作。以下是其核心特性和分类:


一、集合的核心作用

‌1、动态扩展‌
集合可动态调整容量(如 List),相比固定大小的数组更灵活‌。
2、‌多样化数据结构‌
提供栈(Stack)、队列(Queue)、列表(List)、哈希表(Dictionary<TKey,TValue>)等结构,适应不同场景需求‌
3‌、高效操作‌
通过哈希表、平衡树等结构优化查找、插入和删除操作的性能‌


二、C# 集合的核心分类‌

C# 集合主要分为 ‌泛型集合‌ 和 ‌非泛型集合‌,分别位于 System.Collections.Generic 和 System.Collections 命名空间。
此外,还有 ‌线程安全集合‌(System.Collections.Concurrent)和 ‌特殊用途集合‌(如 ObservableCollection)。

核心接口‌
所有集合类型基于以下接口实现:

‌接口‌ ‌作用‌
IEnumerable支持集合遍历(如 foreach)
ICollection定义集合大小、同步操作等基础功能
IList/IDictionary提供索引或键值对访问(如 List、Dictionary)

‌三、常用集合类型详解及对比‌

‌1. 动态数组‌

‌类型‌‌特点‌‌适用场景‌
List泛型动态数组,支持索引、动态扩容,高效增删(尾部操作O(1),中间操作O(n))需频繁修改的强类型数据集合
ArrayList非泛型动态数组,存储object,需装箱/拆箱,类型不安全旧代码兼容,非泛型场景

‌示例代码‌

List<int> numbers = new List<int> { 1, 2, 3 };
numbers.Add(4);  // O(1)(若未扩容)
numbers.RemoveAt(0);  // O(n)

‌2. 键值对集合‌

‌类型‌ ‌特点‌‌适用场景‌
Dictionary<TKey,TValue>泛型哈希表,键唯一,查找/插入/删除接近O(1)高频键值查询(如缓存)
Hashtable非泛型哈希表,键值均为object,性能较低旧代码兼容
SortedDictionary<TKey,TValue>基于红黑树实现,按键排序,插入/删除O(log n)需要有序键值对的场景

‌示例代码‌

Dictionary<string, int> scores = new Dictionary<string, int>();
scores.Add("Alice", 90);  // O(1)
int aliceScore = scores["Alice"];  // O(1)

‌3. 队列与栈‌

‌类型‌ ‌特点‌‌适用场景‌
Queue先进先出(FIFO),入队/出队均为O(1)任务调度、消息缓冲
Stack后进先出(LIFO),入栈/出栈均为O(1)撤销操作、递归模拟

‌示例代码‌

Queue<string> tasks = new Queue<string>();
tasks.Enqueue("Task1");  // O(1)
string nextTask = tasks.Dequeue();  // O(1)

‌4. 链表‌

‌类型‌‌特点‌‌适用场景‌
LinkedList双向链表,插入/删除任意位置O(1)(需先找到节点),内存占用较高高频插入删除,无需索引访问

‌示例代码‌

LinkedList<int> linkedList = new LinkedList<int>();
linkedList.AddLast(10);  // O(1)
linkedList.AddFirst(5);  // O(1)

‌5. 其他特殊集合‌

‌类型‌ ‌特点‌
HashSet无序、唯一元素集合,基于哈希表,查找/插入O(1)
SortedSet有序唯一元素集合,基于红黑树,插入/删除O(log n)
ObservableCollection数据变化时触发通知(如WPF绑定)

四、集合选择的核心原则‌

1‌、数据类型安全‌

  • 优先使用泛型集合(如 List 而非 ArrayList),避免装箱拆箱和运行时错误。

2、‌访问方式‌

  • 按索引访问:List 或数组。
  • 按键访问:Dictionary<TKey,TValue>。

3、‌性能需求‌

  • 高频插入/删除:LinkedList(中间操作)或 List(尾部操作)。
  • 快速查找:哈希表(Dictionary)。

4、‌线程安全‌

  • 多线程场景使用 ConcurrentQueue、ConcurrentDictionary 等并发集合。

5、‌内存效率‌

  • 数据量固定时优先用数组,动态调整时用集合。

‌五、关键区别总结‌

‌集合类型‌‌ 内部结构‌‌‌ 时间复杂度(平均)‌‌ ‌适用场景‌
List‌‌‌动态数组‌‌ 索引访问O(1),中间增删O(n)‌‌ 通用动态数据存储
Dictionary<TKey,TValue>‌ 哈希表‌‌查找/插入/删除接近O(1)‌‌高频键值查询
LinkedList‌双向链表‌插入/删除O(1)‌(需先查找节点)
HashSet‌ 哈希表‌查找/插入/删除O(1)‌‌去重、集合运算(交/并集)
SortedSet‌红黑树‌插入/删除O(log n)‌‌ 需要有序唯一元素的场景

‌六、最佳实践‌

  • 初始化容量‌:预估数据量,避免频繁扩容(如 new List(1000))。
  • ‌避免频繁修改‌:对 List 中间元素的大量增删可改用 LinkedList。
  • 线程安全‌:非并发集合在多线程中需手动加锁,或直接使用 Concurrent 集合。
  • 通过合理选择集合类型,可以在代码可读性、性能和内存效率之间达到最佳平衡。

http://www.ppmy.cn/embedded/174647.html

相关文章

为什么从另一个电脑复制项目文件过来后,QT 在自己电脑上登录界面登不上,Shadow build 被选中原因

### 为什么从另一个电脑复制项目文件过来后&#xff0c;QT 在自己电脑上登录界面登不上&#xff0c;Shadow build 被选中原因 #### 1. **Shadow build 的作用** Shadow build 是 Qt Creator 提供的一种构建模式&#xff0c;将编译生成的中间文件和可执行文件存放在源代码目录之…

Java基础面试题学习

转换成自已的语言来回答&#xff0c;来源小林coding、沉默王二以及其它资源和自已改编。 1、概念 1、说一下Java的特点 我认为Java有很多特点 首先是平台无关性&#xff1a;Java可以实现一次编译到处运行&#xff0c;因为Java的编译器将源代码编译成字节码&#xff0c;使得该…

【搜索页】- 功能流程

【搜索页】- 功能流程 【搜索组件】- 改造搜索组件HdSearch src/main/ets/common/components/HdSearch.ets 课程目标 直接将搜索关键字写死在keywords数组中&#xff1a;keywords:string[][html,css,js,vue,react]使用setInterval实现每隔3秒完成题目分类数据的切换使用rout…

JAVA 中的 HashMap 工作原理

‌1. 底层数据结构‌ ‌数组 链表/红黑树‌&#xff1a; HashMap 内部维护一个 ‌桶数组&#xff08;Node[] table&#xff09;‌&#xff0c;每个桶&#xff08;Bucket&#xff09;存储链表或红黑树的头节点。 transient Node<K,V>[] table; // 桶数组 static class N…

C++基础 [十二] - 继承与派生

目录 前言 什么是继承 继承的概念 继承的定义 基类与派生类对象的赋值转换 继承的作用域 派生类中的默认成员函数 默认成员函数的调用 构造函数与析构函数 拷贝构造 赋值运算符重载 显示成员函数的调用 构造函数 拷贝构造 赋值运算符重载 析构函数 继承与…

Spring Boot中接口数据字段为 Long 类型时,前端number精度丢失问题解决方案

Spring Boot中接口数据字段为 Long 类型时&#xff0c;前端number精度丢失问题解决方案 在Spring Boot中&#xff0c;当接口数据字段为 Long 类型时&#xff0c;返回页面的JSON中该字段通常会被序列化为数字类型。 例如&#xff0c;一个Java对象中有一个 Long 类型的属性 id …

蓝桥杯 第十天 :2022 国赛 第 2 题 排列距离/康托定理

实际上就是求字典序&#xff1a; 假设我们有 3 个数字&#xff1a;1, 2, 3。 排列组合总数: 3! 3 * 2 * 1 6 种。 这 6 种排列分别是&#xff1a; 1 2 31 3 22 1 32 3 13 1 23 2 1 康托展开: 对于排列 2 1 3&#xff0c;康托展开计算的结果是 2。这意味着 2 1 3 在所有 6 种…

JavaScript-函数、对象详解

一、函数 1.为什么需要函数&#xff1f; 作用&#xff1a;封装重复代码&#xff0c;实现复用示例&#xff1a;alert ()、prompt () 等内置函数 2.函数声明与调用 语法&#xff1a; function 函数名() {// 函数体 } 函数名(); // 调用 命名规范&#xff1a; 小驼峰命名&am…