C# 中 ArrayList动态数组、List<T>列表与 Dictionary<T Key, T Value>字典的深度对比
目录
一、基本介绍
二、核心区别对比表
三、常用方法及使用方式对比表
四、适用场景
五、总结
在 C# 中,ArrayList、List<T>和 Dictionary<TKey, TValue> 是常用的集合类型,它们各有特点,适用于不同场景。
一、基本介绍
-
ArrayList:非泛型动态数组,可存储任意类型元素,取出时需强制类型转换。
ArrayList list = new ArrayList(); list.Add(10); list.Add("text"); int num = (int)list[0]; // 需要类型转换
-
List<T>:泛型列表,只能存储指定类型 T 的元素,无需类型转换,类型安全。
List<int> list = new List<int>(); list.Add(10); int num = list[0]; // 直接访问
-
Dictionary<TKey, TValue>:泛型字典,以键值对形式存储,通过唯一 Key 快速访问 Value。
Dictionary<string, int> dict = new(); dict.Add("age", 25); int age = dict["age"]; // 通过Key访问
二、核心区别对比表
特性 | ArrayList | List<T> | Dictionary<TKey, TValue> |
---|---|---|---|
类型安全 | 无(存储 Object,需强制转换) | 有(指定泛型类型,无需转换) | 有(键和值均指定类型) |
存储形式 | 单一元素集合 | 单一元素集合(同类型) | 键值对集合(Key 唯一) |
访问方式 | 索引访问 | 索引访问 | 键访问(支持遍历键 / 值集合) |
装箱拆箱 | 有(值类型存储时) | 无(泛型避免装箱拆箱) | 无(键和值为值类型时无装箱) |
查找效率(平均) | O (n)(需遍历) | O (n)(需遍历,索引访问 O (1)) | O (1)(通过 Key 查找) |
元素唯一性 | 不保证 | 不保证 | 键必须唯一,值可重复 |
命名空间 | System.Collections | System.Collections.Generic | System.Collections.Generic |
三、常用方法及使用方式对比表
操作类型 | ArrayList(非泛型) | List<T>(泛型列表) | Dictionary<TKey, TValue>(泛型字典) |
---|---|---|---|
添加元素 | Add(object value) 参数: - value :要添加到集合中的任意类型元素示例: ArrayList arr = new ArrayList(); arr.Add(10); // 添加整数arr.Add("test"); // 添加字符串 | Add(T item) 参数: - item :要添加到集合中的 T 类型元素(T 为定义时指定的类型)示例: List<int> list = new List<int>(); list.Add(10); // 添加 int 类型元素 | Add(TKey key, TValue value) 参数: - key :用于标识元素的唯一键(TKey 类型)- value :与键关联的值(TValue 类型)示例: Dictionary<string, int> dict = new(); dict.Add("age", 25); //key 为 string,value 为 int |
移除元素 | Remove(object value) 参数: - value :要从集合中移除的元素示例: arr.Remove(10); // 移除值为 10 的元素RemoveAt(int index) 参数: - index :要移除元素的索引位置示例: arr.RemoveAt(0); // 移除第一个元素 | Remove(T item) 参数: - item :要移除的 T 类型元素示例: list.Remove(10); // 移除值为 10 的元素RemoveAt(int index) 参数: - index :要移除元素的索引位置示例: list.RemoveAt(0); // 移除第一个元素 | Remove(TKey key) 参数: - key :要移除的键值对的键示例: dict.Remove("age"); // 移除 key 为 "age" 的键值对RemoveWhere(Predicate<KeyValuePair<TKey,TValue>> match) 参数: - match :判断是否移除的条件委托示例: dict.RemoveWhere(pair => pair.Value < 60); // 移除值小于 60 的键值对 |
清空集合 | Clear() 参数:无 示例: arr.Clear(); // 清空所有元素 | Clear() 参数:无 示例: list.Clear(); // 清空所有元素 | Clear() 参数:无 示例: dict.Clear(); // 清空所有键值对 |
查找元素 | Contains(object value) 参数: - value :要检查是否存在的元素示例: bool has = arr.Contains(10); // 检查是否包含 10IndexOf(object value) 参数: - value :要查找索引的元素示例: int index = arr.IndexOf("test"); // 获取 "test" 的索引 | Contains(T item) 参数: - item :要检查是否存在的 T 类型元素示例: bool has = list.Contains(10); // 检查是否包含 10IndexOf(T item) 参数: - item :要查找索引的 T 类型元素示例: int index = list.IndexOf(20); // 获取 20 的索引Find(Predicate<T> match) 参数: - match :匹配条件的委托示例: int val = list.Find(x => x > 15); // 查找第一个大于 15 的元素 | ContainsKey(TKey key) 参数: - key :要检查是否存在的键示例: bool has = dict.ContainsKey("age"); // 检查是否包含 "age" 键TryGetValue(TKey key, out TValue value) 参数: - key :要查找的键- value :输出参数,存储找到的值(未找到时为默认值)示例: dict.TryGetValue("score", out int score); // 安全获取 "score" 对应的值 |
获取长度 元素个数 | Count(属性) 参数:无 示例: int len = arr.Count; // 获取元素总数 | Count(属性) 参数:无 示例: int len = list.Count; // 获取元素总数 | Count(属性) 参数:无 示例: int len = dict.Count; // 获取键值对总数 |
获取 / 修改元素 | this [int index](索引器) 参数: - index :元素的索引位置示例: int val = (int)arr[0]; // 获取第一个元素(需类型转换)arr[0] = 20; // 修改第一个元素 | this [int index](索引器) 参数: - index :元素的索引位置示例: int val = list[0]; // 获取第一个元素list[0] = 20; // 修改第一个元素 | this [TKey key](索引器) 参数: - key :元素的键示例: int age = dict["age"]; // 获取 "age" 对应的值dict["age"] = 26; // 修改 "age" 对应的值 |
其他常用 | Sort() 参数:无(对元素排序) 示例: arr.Sort(); ToArray() 参数:无(转换为数组) 示例: object[] arr2 = arr.ToArray(); | AddRange(IEnumerable<T> collection) 参数: - collection :要添加的元素集合示例: list.AddRange(new int[]{30,40}); // 批量添加Sort() 参数:无(对元素排序) 示例: list.Sort(); | Keys(属性) 参数:无(获取所有键) 示例: foreach (var key in dict.Keys) { ... } Values(属性) 参数:无(获取所有值) 示例: foreach (var val in dict.Values) { ... } |
方法使用要点
- ArrayList 由于是非泛型集合,在获取元素时需要进行类型转换,如
(int)arr[0]
,否则会出现编译错误。 - List<T>的
Find
方法非常实用,通过 lambda 表达式可以快速查找符合条件的元素,避免了手动遍历。 - Dictionary 的
TryGetValue
方法比直接通过键获取值更安全,当键不存在时不会抛出异常,而是返回 false,适合不确定键是否存在的场景。 - 对于批量添加元素,List<T>的
AddRange
方法比多次调用Add
方法效率更高。
四、适用场景
- ArrayList:需存储混合类型,且对性能要求不高的场景(现已少用)。
- List<T>:存储同类型元素,需频繁添加、删除或按索引访问(最常用)。
- Dictionary:需通过唯一标识(Key)快速查找数据,如 ID 查信息。
五、总结
- 优先用 List<T>替代 ArrayList,兼顾类型安全与性能。
- 需要快速键值查找时,选 Dictionary。
- 根据数据类型和访问方式选择合适集合,可提升代码效率。
之前的文章~
C# _列表(List<T>)_ 字典(Dictionary<TKey, TValue>)https://blog.csdn.net/LZQqqqqo/article/details/149754745?spm=1001.2014.3001.5502C#_ArrayList动态数组
https://blog.csdn.net/LZQqqqqo/article/details/149752917?spm=1001.2014.3001.5502