VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 编程开发 > c#编程 >
  • 常用集合:List、Dictionary、HashSet

常用集合:List、Dictionary、HashSet
概述
集合是C#中用于存储多个数据的容器,相比数组(固定长度、类型单一),集合具有vb.net教程C#教程python教程SQL教程access 2010教程动态扩容、类型安全、功能丰富等优势。本节聚焦三个最常用的泛型集合:
List:动态数组,支持索引访问,适合有序存储;
Dictionary<TKey, TValue>:键值对集合,通过键快速查找值;
HashSet:无重复元素的集合,适合去重和集合运算。

  1. List:动态数组
    List是泛型动态数组,可自动扩容,支持索引访问、添加/删除元素等操作,是日常开发中最常用的集合之一。
    1.1 实例代码:管理学生姓名
    csharp
	using System;
	using System.Collections.Generic;
	
	class Program
	{
	static void Main()
	{
	// 1. 初始化List:指定存储string类型,初始容量为5(可选,优化性能)
	List<string> students = new List<string>(5);
	
	// 2. 添加元素到末尾
	students.Add("张三");
	students.Add("李四");
	students.Add("王五");
	
	// 3. 插入元素到指定位置(索引1)
	students.Insert(1, "赵六");
	
	// 4. 访问元素(通过索引)
	Console.WriteLine("索引2的学生:" + students[2]); // 输出:李四
	
	// 5. 修改元素(通过索引)
	students[3] = "王麻子";
	
	// 6. 删除元素(按值删除第一个匹配项)
	students.Remove("张三");
	
	// 7. 遍历元素(foreach)
	Console.WriteLine("
遍历学生列表:");
	foreach (string name in students)
	{
	Console.WriteLine(name); // 输出:赵六、李四、王麻子
	}
	
	// 8. 遍历元素(for循环,通过索引)
	Console.WriteLine("
通过索引遍历:");
	for (int i = 0; i < students.Count; i++)
	{
	Console.WriteLine($"索引{i}{students[i]}");
	}
	
	// 9. 查找元素(Lambda表达式)
	string foundStudent = students.Find(name => name.StartsWith("李"));
	Console.WriteLine("
找到以'李'开头的学生:" + foundStudent); // 输出:李四
	}
	}

1.2 逐行讲解
初始化:List students = new List(5)创建一个存储字符串的List,初始容量为5(默认容量是4,满了自动翻倍);
添加元素:Add在末尾添加,Insert(1, "赵六")在索引1位置插入(后续元素后移);
访问/修改:通过索引students[2]访问,直接赋值修改;
删除:Remove("张三")删除第一个匹配的元素;
遍历:foreach适合简单遍历,for循环适合需要索引的场景;
查找:Find方法用Lambda表达式查找第一个符合条件的元素(如以“李”开头)。
1.3 基础知识拓展
容量与性能优化
List的容量(Capacity)是当前可容纳的最大元素数,计数(Count)是实际元素数。当Count > Capacity时,List会自动扩容(默认翻倍),这会消耗性能。如果提前知道元素数量,初始化时指定容量可优化:
csharp
// 预计存储100个学生,直接指定容量
List largeList = new List(100);
常用方法
RemoveAt(int index):删除指定索引的元素;
Sort():对元素排序(需实现IComparable或自定义比较器);
ToArray():转换为数组;
Clear():清空所有元素。

  1. Dictionary<TKey, TValue>:键值对集合
    Dictionary是泛型键值对集合,通过键(Key)快速查找值(Value),键具有唯一性(不可重复)。
    2.1 实例代码:存储学生ID与姓名
    csharp
	using System;
	using System.Collections.Generic;
	
	class Program
	{
	static void Main()
	{
	// 1. 初始化Dictionary:键为int(学生ID),值为string(姓名)
	Dictionary<int, string> studentDict = new Dictionary<int, string>();
	
	// 2. 添加键值对(键唯一,重复会抛异常)
	studentDict.Add(101, "张三");
	studentDict.Add(102, "李四");
	studentDict.Add(103, "王五");
	
	// 3. 安全添加(避免重复键异常)
	bool added = studentDict.TryAdd(104, "赵六");
	Console.WriteLine("是否添加成功:" + added); // 输出:True
	
	// 4. 访问值(通过键)
	Console.WriteLine("ID102的姓名:" + studentDict[102]); // 输出:李四
	
	// 5. 修改值(通过键赋值)
	studentDict[103] = "王麻子";
	
	// 6. 删除键值对(通过键)
	studentDict.Remove(101);
	
	// 7. 遍历键值对
	Console.WriteLine("
遍历键值对:");
	foreach (KeyValuePair<int, string> kvp in studentDict)
	{
	Console.WriteLine($"ID:{kvp.Key},姓名:{kvp.Value}");
	}
	
	// 8. 安全获取值(避免键不存在异常)
	bool found = studentDict.TryGetValue(105, out string nameOut);
	Console.WriteLine("
是否找到ID105:" + found); // 输出:False
	Console.WriteLine("获取的姓名:" + nameOut); // 输出:null
	}
	}

2.2 逐行讲解
初始化:Dictionary<int, string>指定键为int、值为string;
添加:Add方法要求键唯一,TryAdd更安全(返回是否添加成功);
访问/修改:通过键studentDict[102]访问值,直接赋值修改;
删除:Remove(101)通过键删除整个键值对;
遍历:KeyValuePair同时获取键和值,也可单独遍历Keys或Values;
安全获取:TryGetValue避免键不存在时抛出KeyNotFoundException。
2.3 基础知识拓展
键的要求
Dictionary的键必须是不可变类型(如int、string),因为键的哈希码(用于快速查找)不能改变。如果用自定义类型作为键,需重写GetHashCode和Equals方法:
csharp

	public class StudentKey
	{
	public int Id { get; }
	public StudentKey(int id) => Id = id;
	
	// 重写哈希码(基于Id)
	public override int GetHashCode() => Id.GetHashCode();
	
	// 重写Equals(判断Id是否相等)
	public override bool Equals(object obj) => obj is StudentKey key && Id == key.Id;
	}

性能优势
Dictionary的查找速度是O(1)(几乎瞬间),因为基于哈希表实现:通过键的哈希码直接定位值,比List的Contains(O(n))快得多。

  1. HashSet:无重复元素的集合
    HashSet是无重复元素的泛型集合,基于哈希表实现,适合去重和集合运算(交集、并集、差集)。
    3.1 实例代码:存储不重复数字
    csharp
	using System;
	using System.Collections.Generic;
	
	class Program
	{
	static void Main()
	{
	// 1. 初始化HashSet:存储int类型
	HashSet<int> numbers = new HashSet<int>();
	
	// 2. 添加元素(自动去重)
	numbers.Add(1);
	numbers.Add(2);
	numbers.Add(3);
	numbers.Add(2); // 重复元素,自动忽略
	
	// 3. 判断元素是否存在(O(1)时间复杂度)
	bool has2 = numbers.Contains(2);
	Console.WriteLine("是否包含2:" + has2); // 输出:True
	
	// 4. 删除元素
	numbers.Remove(3);
	
	// 5. 遍历元素
	Console.WriteLine("
遍历HashSet:");
	foreach (int num in numbers)
	{
	Console.WriteLine(num); // 输出:1、2
	}
	
	// 6. 集合运算(交集、并集、差集)
	HashSet<int> setA = new HashSet<int> { 1, 2, 3, 4 };
	HashSet<int> setB = new HashSet<int> { 3, 4, 5, 6 };
	
	// 交集(共同元素)
	setA.IntersectWith(setB);
	Console.WriteLine("
交集(A∩B):");
	foreach (int num in setA) Console.WriteLine(num); // 输出:3、4
	
	// 重置setA
	setA = new HashSet<int> { 1, 2, 3, 4 };
	
	// 并集(所有元素,去重)
	setA.UnionWith(setB);
	Console.WriteLine("
并集(A∪B):");
	foreach (int num in setA) Console.WriteLine(num); // 输出:1、2、3、4、5、6
	}
	}

3.2 逐行讲解
初始化:HashSet numbers = new HashSet()创建无重复的数字集合;
添加:Add方法自动忽略重复元素(如第二次添加2无效);
判断存在:Contains方法速度极快(O(1));
遍历:用foreach遍历(无索引,因为元素无序);
集合运算:IntersectWith(交集)、UnionWith(并集)、ExceptWith(差集)直接修改原集合。
3.3 基础知识拓展
与List的区别

特性 List HashSet
重复元素 允许 禁止
索引访问 支持 不支持
Contains速度 O(n)(慢) O(1)(快)
集合运算 无内置方法 支持(交集、并集等)

适用场景
需要去重时:如存储用户输入的不重复关键词;
判断元素是否存在时:如验证用户名是否已注册;
集合运算时:如计算两个用户群体的共同兴趣。

总结
三个集合的核心适用场景:
List:需要动态扩容、索引访问、允许重复元素的场景(如存储订单列表);
Dictionary<TKey, TValue>:需要键值映射、快速查找的场景(如存储用户ID与信息);
HashSet:需要去重、快速判断存在性、集合运算的场景(如存储不重复的标签)。
掌握这三个集合,可解决80%以上的C#数据存储问题。
(本节完)
下一章:LINQ进阶:分组与连接查询
(深入讲解GroupBy、Join等复杂LINQ操作)


本站原创,转载请注明出处:https://www.xin3721.com/ArticlecSharp/c49381.html


相关教程