C#常用集合的使用

C#常用集合的使用

大多数集合都在System.Collections,System.Collections.Generic两个命名空间。其中System.Collections.Generic专门用于泛型集合。
针对特定类型的集合类型位于System.Collections.Specialized;命名空间;线程安全的集合类位于System.Collections.Concurrent;命名空间。
下面是集合和列表实现的接口如下:


List

底层数组实现

初始化

c# 复制代码
// 创建空列表
var list1 = new List<int>();
for (int i = 1; i <= 10; i++)
{
    list1.Add(i);
}
Console.WriteLine(list1.Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));

// 使用大括号初始化
var list2 = new List<int>() { 100, 200, 300 };
Console.WriteLine(list2.Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));

// 从其他集合构造
var list3 = new List<int>(list1);
list3.AddRange(list2);
Console.WriteLine(list3.Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));

// 集合表达式
List<int> list4 = [101, 102, 103, 104];
Console.WriteLine(list4.Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));

信息查询

c# 复制代码
// 集合表达式
List<int> list1 = [101, 102, 103, 104];
Console.WriteLine("Capacity: " + list1.Capacity);
Console.WriteLine("Count: " + list1.Count);
Console.WriteLine("TrueForAll: " + list1.TrueForAll(it => it % 2 == 0));
Console.WriteLine("Exists: " + list1.Exists(it => it % 2 == 0));

添加元素

c# 复制代码
List<int> list1 = [101, 102, 103, 104];
// 添加单个元素
list1.Add(1);

// 添加多个元素
list1.AddRange(new List<int> { 20, 21, 22 });

Console.WriteLine(list1.Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));

插入元素

c# 复制代码
List<int> list1 = [101, 102, 103, 104];
// 插入单个元素
list1.Insert(0, 1);

// 插入多个元素
list1.InsertRange(0, new List<int> { 20, 21, 22 });

Console.WriteLine(list1.Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));

访问元素

c# 复制代码
List<int> list1 = [101, 102, 103, 104];
// 根据索引查询修改
list1[0] = 1;

// ElementAt(0)  ,越界抛异常
Console.WriteLine("ElementAt(0)=" + list1.ElementAt(0));

// ElementAtOrDefault(0) ,越界返回默认值
Console.WriteLine("ElementAtOrDefault(0)=" + list1.ElementAtOrDefault(100));

查找元素

c# 复制代码
List<int> list1 = [101, 102, 103, 104];

// Contains
Console.WriteLine("Contains(101)=" + list1.Contains(101));

// IndexOf , 未找到返回 -1
Console.WriteLine("IndexOf(101)=" + list1.IndexOf(101));

// Find , 查找第一个匹配条件的元素
Console.WriteLine("Find=" + list1.Find(it => it % 2 == 0));

// FindLast , 返回最后一个匹配元素
Console.WriteLine("FindLast=" + list1.FindLast(it => it % 2 == 0));

// FindAll, 查找所有匹配条件的元素
Console.WriteLine("FindAll=" + list1.FindAll(it => it % 2 == 0).Count);

// FindIndex , 返回第一个匹配元素的索引
Console.WriteLine("FindIndex=" + list1.FindIndex(it => it % 2 == 0));

// FindLastIndex , 返回最后一个匹配元素的索引
Console.WriteLine("FindLastIndex=" + list1.FindLastIndex(it => it % 2 == 0));

删除元素

c# 复制代码
List<int> list1 = [101, 102, 103, 104, 105, 106, 107, 108, 109, 110];

// Remove , 删除第一个匹配项(成功返回 true)
list1.Remove(101);
Console.WriteLine("list: " + list1.Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));

// RemoveAt , 按索引删除
list1.RemoveAt(0);
Console.WriteLine("list: " + list1.Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));

// RemoveAll , 删除所有匹配项,返回删除数量
list1.RemoveAll(it => it % 3 == 0);
Console.WriteLine("list: " + list1.Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));

// RemoveRange , 按索引删除指定数量
list1.RemoveRange(0, 2);
Console.WriteLine("list: " + list1.Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));

// Clear , 清空所有元素
list1.Clear();
Console.WriteLine("list: " + list1.Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));

遍历

c# 复制代码
List<int> list1 = [101, 102, 103, 104, 105, 106, 107, 108, 109, 110];
// for
Console.Write("for: ");
for (int i = 0; i < list1.Count; i++)
{
    Console.Write(list1[i] + ", ");
}
Console.WriteLine();

// foreach
Console.Write("foreach: ");
foreach (var it in list1)
{
    Console.Write(it + ", ");
}
Console.WriteLine();

// ForEach
Console.Write("ForEach: ");
list1.ForEach(it => Console.Write(it + ", "));
Console.WriteLine();

// ConvertAll
Console.Write("ConvertAll: ");
list1.ConvertAll(it => it.ToString()).ForEach(it => Console.Write(it + ", "));
Console.WriteLine();

排序

c# 复制代码
List<int> list1 = [101, 102, 103, 104, 105, 106, 107, 108, 109, 110];

// Sort,自定义排序
list1.Sort((a, b) => b.CompareTo(a));
Console.WriteLine(list1.Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));

// Sort , 默认ASC排序
list1.Sort();
Console.WriteLine(list1.Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));

// Reverse , 反转元素
list1.Reverse();
Console.WriteLine(list1.Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));

结果转换

c# 复制代码
List<int> list1 = [101, 102, 103, 104, 105, 106, 107, 108, 109, 110];

// ToArray
int[] array = list1.ToArray();
foreach (var it in array)
{
    Console.Write(it + ", ");
}
Console.WriteLine();

其他

c# 复制代码
      List<int> list1 = [101, 102, 103, 104, 105, 106, 107, 108, 109, 110];

      // 分割成指定大小的块
      var ll = list1.Chunk(3);
      foreach (var l in ll)
      {
          foreach (var it in l)
          {
              Console.Write(it + ", ");
          }
          Console.WriteLine();
      }

LinkedList

  • 底层双向链表 (每个节点含 PrevNext 指针)
  • 内部使用 LinkedListNode<T> 表示节点
  • 允许重复值
  • 允许 null 值
操作 LinkedList<T> List<T> Queue<T> Stack<T>
头部插入 O(1) O(n) --- ---
尾部插入 O(1) O(1) amortized O(1) O(1)
中间插入(有引用) O(1) O(n)
按索引访问 O(1)
遍历性能 慢(指针跳转) 快(连续内存)
内存开销
对比维度 LinkedList<T> List<T>
底层数据结构 双向链表(每个节点含 Prev/Next 指针) 动态数组(连续内存块)
内存布局 节点分散在堆上(非连续) 元素紧密排列(连续内存)
是否支持索引访问 ❌ 不支持 list[0](无索引器) ✅ 支持 list[i](O(1))
插入/删除(头部) O(1)AddFirst / RemoveFirst O(n)(需移动所有元素)
插入/删除(尾部) O(1)AddLast / RemoveLast O(1) 平均(偶尔扩容 O(n))
插入/删除(中间) O(1)已有 LinkedListNode<T> 引用时 ) ❌ O(n) (仅知值,需先 Find O(n)(需移动后续元素)
按值查找 O(n)Find() 从头遍历) O(n)IndexOf() 遍历)
遍历性能 较慢(指针跳转,缓存不友好) 快(连续内存,CPU 缓存命中率高)
内存开销 高(每元素额外 2 个指针 ≈ +16 字节/节点 on 64-bit) 低(仅数组 + 少量元数据)
容量管理 Capacity 概念 ✅ 有 Capacity(.NET 8 中为只读
初始化语法(C# 12) ✅ 支持集合表达式: LinkedList<int> ll = [1, 2, 3]; ✅ 支持: List<int> list = [1, 2, 3];
线程安全 ❌ 非线程安全 ❌ 非线程安全
允许重复元素 ✅ 是 ✅ 是
允许 null 值 ✅ 是(若 T 为引用类型) ✅ 是
迭代中修改安全性 ✅ 可通过 node 安全删除(不影响其他节点) foreach 中修改抛 InvalidOperationException
场景 推荐类型 原因
频繁在开头/结尾增删(如队列/栈) LinkedList<T> 或专用 Queue<T>/Stack<T> O(1) 操作
需要随机访问 (如 list[i] List<T> 唯一支持索引器
大量中间插入/删除(且持有位置引用) LinkedList<T> O(1) 修改
顺序遍历 + 少量修改 List<T> 缓存友好,实际更快
内存极度敏感 List<T> 无额外指针开销
实现 LRU 缓存双向游标 LinkedList<T> 节点可长期持有并 O(1) 移动

初始化

c# 复制代码
var list1 = new LinkedList<int>();
for (int i = 1; i <= 10; i++)
{
    list1.AddLast(i);
}
Console.WriteLine(list1.Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));

// 从其他集合构造
var list2 = new LinkedList<int>(list1);
Console.WriteLine(list2.Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));

信息查询

c# 复制代码
var list1 = new LinkedList<int>();
for (int i = 1; i <= 10; i++)
{
    list1.AddLast(i);
}
Console.WriteLine("Count: " + list1.Count);
Console.WriteLine("Exists: " + list1.Contains(10));

添加元素

c# 复制代码
var list1 = new LinkedList<int>();
for (int i = 1; i <= 10; i++)
{
    // 在尾部添加新节点
    list1.AddLast(i);
}

// AddFirst 在头部添加新节点
list1.AddFirst(100);
Console.WriteLine(list1.Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));

// AddBefore 在指定节点前插入
var node = list1.Find(100);
if (node != null)
{
    list1.AddBefore(node, 101);
}

// AddAfter 在指定节点后插入
if (node != null)
{
    list1.AddAfter(node, 102);
}
Console.WriteLine(list1.Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));

删除元素

c# 复制代码
var list1 = new LinkedList<int>();
for (int i = 1; i <= 10; i++)
{
    // 在尾部添加新节点
    list1.AddLast(i);
}

// Remove , 删除第一个匹配项(成功返回 true)
list1.Remove(101);
Console.WriteLine("list: " + list1.Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));

// Remove 删除指定节点(O(1))
var node = list1.Find(5);
if (node != null)
{
    list1.Remove(node);
    Console.WriteLine("list: " + list1.Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));
}

// RemoveFirst 删除头节点
list1.RemoveFirst();
Console.WriteLine("list: " + list1.Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));

// RemoveLast , 删除尾节点
list1.RemoveLast();
Console.WriteLine("list: " + list1.Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));

// Clear , 清空所有元素
list1.Clear();
Console.WriteLine("list: " + list1.Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));

访问元素

c# 复制代码
var list1 = new LinkedList<int>();
for (int i = 1; i <= 10; i++)
{
    // 在尾部添加新节点
    list1.AddLast(i);
}

// First  ,获取头节点
Console.WriteLine("First=" + list1.First());

// Last ,获取尾节点
Console.WriteLine("Last=" + list1.Last());

遍历

c# 复制代码
var list1 = new LinkedList<int>();
for (int i = 1; i <= 10; i++)
{
    // 在尾部添加新节点
    list1.AddLast(i);
}

// foreach
Console.Write("foreach: ");
foreach (var it in list1)
{
    Console.Write(it + ", ");
}
Console.WriteLine();

// for
Console.Write("for: ");
for (var n = list1.First; n != null; n = n.Next)
{
    Console.Write(n.Value + ", ");
}
Console.WriteLine();

Dictionary

初始化

c# 复制代码
// 创建空字典
var dict1 = new Dictionary<string, int>();
dict1.Add("A", 1);
dict1.Add("B", 2);
Console.WriteLine(dict1.Select(it => "(" + it.Key + "->" + it.Value + ")").Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));

// 使用大括号初始化
var dict2 = new Dictionary<string, int> { { "C", 3 }, { "D", 4 } };
Console.WriteLine(dict2.Select(it => "(" + it.Key + "->" + it.Value + ")").Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));

容量信息

c# 复制代码
var dict1 = new Dictionary<string, int>(10);
dict1.Add("A", 1);
dict1.Add("B", 2);

Console.WriteLine("Count: " + dict1.Count);
Console.WriteLine("Keys: " + dict1.Keys.Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));
Console.WriteLine("Values: " + dict1.Values.Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));

添加元素

c# 复制代码
var dict1 = new Dictionary<string, int>(10);

// Add ,键存在则抛异常
dict1.Add("A", 1);
dict1.Add("B", 2);
Console.WriteLine(dict1.Select(it => "(" + it.Key + "->" + it.Value + ")").Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));

// TryAdd , 当键不存在时添加成功
dict1.TryAdd("A", 1);
dict1.TryAdd("C", 3);
Console.WriteLine(dict1.Select(it => "(" + it.Key + "->" + it.Value + ")").Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));

//通过索引器, 若存在则更新,否则新增
dict1["A"] = 11;
dict1["D"] = 4;
Console.WriteLine(dict1.Select(it => "(" + it.Key + "->" + it.Value + ")").Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));

删除元素

c# 复制代码
var dict1 = new Dictionary<string, int>(10);
dict1.Add("A", 1);
dict1.Add("B", 2);
dict1.TryAdd("C", 3);
dict1["D"] = 4;

// Remove , 删除指定键(返回是否成功)
dict1.Remove("AAA");
dict1.Remove("A");
Console.WriteLine(dict1.Select(it => "(" + it.Key + "->" + it.Value + ")").Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));

// Remove 输出
dict1.Remove("B", out int val);
Console.WriteLine(dict1.Select(it => "(" + it.Key + "->" + it.Value + ")").Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));

// Clear 清空
dict1.Clear();
Console.WriteLine(dict1.Select(it => "(" + it.Key + "->" + it.Value + ")").Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));

访问元素

c# 复制代码
var dict1 = new Dictionary<string, int>(10);
dict1.Add("A", 1);
dict1.Add("B", 2);
dict1.TryAdd("C", 3);
dict1["D"] = 4;

// 索引器
Console.WriteLine("索引器= " + dict1["A"]);

// TryGetValue
dict1.TryGetValue("A", out int val);
Console.WriteLine("val= " + val);

// ContainsKey
Console.WriteLine("ContainsKey= " + dict1.ContainsKey("A"));

// ContainsValue
Console.WriteLine("ContainsKey= " + dict1.ContainsValue(3));

// Contains
Console.WriteLine("Contains= " + dict1.Contains(new KeyValuePair<string, int>("A", 1)));

遍历

c# 复制代码
var dict1 = new Dictionary<string, int>(10);
dict1.Add("A", 1);
dict1.Add("B", 2);
dict1.TryAdd("C", 3);
dict1["D"] = 4;

// foreach
foreach (var item in dict1)
{
    Console.Write("(" + item.Key + "," + item.Value + "), ");
}
Console.WriteLine();

// Keys
foreach (var item in dict1.Keys)
{
    Console.Write(item + ", ");
}
Console.WriteLine();

// Values
foreach (var item in dict1.Values)
{
    Console.Write(item + ", ");
}
Console.WriteLine();

SortedDictionary

  • 基于红黑树实现
  • 自动排序
  • 键必须可比较
  • SortedDictionary不能设置容量

使用方法与Dictionary基本一致

需求 推荐类型
按键从小到大输出 SortedDictionary
只关心快速查找,顺序无所谓 Dictionary
频繁插入/删除,且数据量大(>10万) Dictionary(性能更优)
经常要找最大/最小键 SortedDictionary
内存非常紧张 Dictionary(更紧凑)或考虑 SortedList(若数据静态)
偶尔排序一次即可 Dictionary + .OrderBy(kvp => kvp.Key)
c# 复制代码
var dict1 = new SortedDictionary<string, int>();
dict1.Add("A", 1);
dict1.Add("B", 2);
dict1.TryAdd("C", 3);
dict1["D"] = 4;

Console.WriteLine("key最小值: " + dict1.Keys.First());
Console.WriteLine("key最大值: " + dict1.Keys.Last());

SortedList

  • 使用两个并行数组存储键和值(支持按索引访问)
  • 自动排序
  • 键唯一且不可 null(值可为 null)
    SortedList 特有功能(Dictionary 没有)
特性 说明
RemoveAt(int index) 整数索引删除元素(如删除第 0 个即最小键)
通过索引直接访问键/值 sl.Keys[i]sl.Values[i] 是 O(1) 操作
可设置/获取 Capacity Dictionary 不同,.NET 8 中 SortedList.Capacity 仍可写
特性对比
特性 Dictionary SortedDictionary SortedList
底层结构 哈希表 红黑树 两个有序数组
插入/删除 O(1) 平均 O(log n) O(n)
查找(键) O(1) 平均 O(log n) O(log n)
按索引访问 ❌ 不支持 ❌ 不支持 O(1)
RemoveAt(index)
内存占用 高(节点指针)
是否有序
可设置 Capacity ❌(.NET 8 只读) ❌(无此概念) 可读写

初始化

c# 复制代码
// 创建空列表
var sl1 = new SortedList<string, int>();
sl1.Add("A", 1);
sl1.Add("B", 2);
sl1.TryAdd("C", 3);
sl1["D"] = 4;
Console.WriteLine(sl1.Select(it => "(" + it.Key + "->" + it.Value + ")").Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));

// 指定大小,避免底层数组频繁扩容
var sl2 = new SortedList<string, int>(10);

// 指定比较器
var sl3 = new SortedList<string, int>(10, StringComparer.OrdinalIgnoreCase);

// 大括号初始化
var sl4 = new SortedList<string, int> { { "A", 1 }, { "B", 2 } };
Console.WriteLine(sl4.Select(it => "(" + it.Key + "->" + it.Value + ")").Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));

容量信息

c# 复制代码
var sl1 = new SortedList<string, int>(10);
sl1.Add("A", 1);
sl1.Add("B", 2);
sl1.TryAdd("C", 3);
sl1["D"] = 4;

// 容量
Console.WriteLine("Capacity: " + sl1.Capacity);
Console.WriteLine("Count: " + sl1.Count);

添加元素

c# 复制代码
var sl1 = new SortedList<string, int>(10);
// Add ,键存在则抛异常
sl1.Add("A", 1);
sl1.Add("B", 2);
Console.WriteLine(sl1.Select(it => "(" + it.Key + "->" + it.Value + ")").Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));

// TryAdd , 当键不存在时添加成功
sl1.TryAdd("A", 1);
sl1.TryAdd("C", 3);
Console.WriteLine(sl1.Select(it => "(" + it.Key + "->" + it.Value + ")").Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));

删除元素

c# 复制代码
var sl1 = new SortedList<string, int>(10);
sl1.Add("A", 1);
sl1.Add("B", 2);
sl1.TryAdd("C", 3);
sl1["D"] = 4;

// Remove , 删除指定键(返回是否成功)
sl1.Remove("AAA");
sl1.Remove("A");
Console.WriteLine(sl1.Select(it => "(" + it.Key + "->" + it.Value + ")").Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));

// Remove 输出
sl1.Remove("B", out int val);
Console.WriteLine(sl1.Select(it => "(" + it.Key + "->" + it.Value + ")").Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));

// RemoveAt 按索引位置删除
sl1.RemoveAt(0);
Console.WriteLine(sl1.Select(it => "(" + it.Key + "->" + it.Value + ")").Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));

// Clear 清空
sl1.Clear();
Console.WriteLine(sl1.Select(it => "(" + it.Key + "->" + it.Value + ")").Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));

访问元素

c# 复制代码
var sl1 = new SortedList<string, int>(10);
sl1.Add("A", 1);
sl1.Add("B", 2);
sl1.TryAdd("C", 3);
sl1["D"] = 4;

// 索引器
Console.WriteLine("索引器= " + sl1["A"]);

// 按索引访问
Console.WriteLine("Keys索引访问= " + sl1.Keys[0]);
Console.WriteLine("Values索引访问= " + sl1.Values[0]);

// TryGetValue
sl1.TryGetValue("A", out int val);
Console.WriteLine("val= " + val);

// ContainsKey
Console.WriteLine("ContainsKey= " + sl1.ContainsKey("A"));

// ContainsValue
Console.WriteLine("ContainsKey= " + sl1.ContainsValue(3));

// Contains
Console.WriteLine("Contains= " + sl1.Contains(new KeyValuePair<string, int>("A", 1)));

遍历

c# 复制代码
var sl1 = new SortedList<string, int>(10);
sl1.Add("A", 1);
sl1.Add("B", 2);
sl1.TryAdd("C", 3);
sl1["D"] = 4;

// foreach
foreach (var item in sl1)
{
    Console.Write("(" + item.Key + "," + item.Value + "), ");
}
Console.WriteLine();

// Keys
foreach (var item in sl1.Keys)
{
    Console.Write(item + ", ");
}
Console.WriteLine();

// Values
foreach (var item in sl1.Values)
{
    Console.Write(item + ", ");
}
Console.WriteLine();

HashSet

  • 底层基于哈希表实现
  • 不重复、无序、可以为null
  • 相等判断使用 IEqualityComparer<T>(默认为 EqualityComparer<T>.Default

初始化

c# 复制代码
// 创建空集合
var set1 = new HashSet<int>();
for (int i = 1; i <= 10; i++)
{
  set1.Add(i);
}
// 容量       
Console.WriteLine("Count: " + set1.Count);
Console.WriteLine(set1.Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));

// 指定容量
var set2 = new HashSet<int>(10);

// 指定比较器
var set3 = new HashSet<string>(10, StringComparer.OrdinalIgnoreCase);

// 大括号初始化
var set4 = new HashSet<int> { 1, 2, 3 };

// 从其他集合构造
var set5 = new HashSet<int>(new List<int> { 1, 2, 3 });

增删操作

c# 复制代码
// 创建空集合
var set1 = new HashSet<int>();
for (int i = 1; i <= 10; i++)
{
    set1.Add(i);
}
Console.WriteLine(set1.Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));

// 添加元素(若不存在),返回 bool:是否成功添加
set1.Add(1);
set1.Add(11);
Console.WriteLine(set1.Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));

// UnionWith 批量添加(并集)
set1.UnionWith(new HashSet<int> { 1, 100, 101, 102 });
Console.WriteLine(set1.Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));

// Remove 删除指定元素,返回 bool:是否存在并被删
set1.Remove(1000);
set1.Remove(1);
Console.WriteLine(set1.Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));

// RemoveWhere 删除所有满足条件的元素, 返回删除数量
set1.RemoveWhere(it => it % 3 == 0);
Console.WriteLine(set1.Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));

// Clear 清空所有元素
set1.Clear();
Console.WriteLine(set1.Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));

查询遍历

c# 复制代码
// 创建空集合
var set1 = new HashSet<int>();
for (int i = 1; i <= 10; i++)
{
    set1.Add(i);
}

// Contains
Console.WriteLine("Contains: " + set1.Contains(5));

// TryGetValue
set1.TryGetValue(5, out var val);
Console.WriteLine("TryGetValue: " + val);

// foreach
Console.Write("foreach: ");
foreach (var it in set1)
{
    Console.Write(it + ", ");
}
Console.WriteLine();

集合运算

c# 复制代码
var set1 = new HashSet<int>();
for (int i = 1; i <= 10; i++)
{
    set1.Add(i);
}

var set2 = new HashSet<int> { 1, 2, 3 };

// IsSubsetOf 是否为子集
Console.WriteLine("IsSubsetOf= " + set2.IsSubsetOf(set1));

// IsSupersetOf 是否为超集
Console.WriteLine("IsSupersetOf= " + set2.IsSupersetOf(set1));

// Overlaps 是否有交集
Console.WriteLine("Overlaps= " + set2.Overlaps(set1));

// SetEquals 是否元素完全相同(忽略顺序)
Console.WriteLine("SetEquals= " + set2.SetEquals(set1));

// IntersectWith 交集(保留共同部分)
set1.IntersectWith(set2);
Console.WriteLine(set1.Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));

// ExceptWith 差集(移除交集部分)
set1.ExceptWith(set2);
Console.WriteLine(set1.Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));

// SymmetricExceptWith 对称差集(A∪B - A∩B)        
set1.SymmetricExceptWith(set2);
Console.WriteLine(set1.Select(it => it.ToString()).Aggregate(string.Empty, (a, b) => a + ", " + b));

SortedSet

  • 底层红黑树(自平衡二叉搜索树
  • 自动排序、无重复元素、可以为null

大部分方法跟HashSet一样
SortedSet特有的

成员 类型 说明 示例
.Min 属性 获取集合中最小元素(O(1)) int low = set.Min;
.Max 属性 获取集合中最大元素(O(1)) int high = set.Max;
.GetViewBetween(T lower, T upper) 方法 返回闭区间 [lower, upper]动态视图(O(log n) 创建) var range = set.GetViewBetween(10, 20);
.Reverse() 方法 返回一个逆序遍历的可枚举对象(不修改原集合) foreach (var x in set.Reverse()) { ... }
构造函数重载:SortedSet<T>(IComparer<T> comparer) 构造器 接受 IComparer<T>(用于排序) ⚠️ HashSet<T> 接受的是 IEqualityComparer<T>(用于哈希相等) new SortedSet<string>(StringComparer.OrdinalIgnoreCase)
能力 是否为 SortedSet<T> 独有 说明
✅ 按排序顺序存储元素 HashSet<T> 无序
✅ O(1) 获取 Min / Max HashSet<T> 需 O(n)
✅ 高效范围查询(GetViewBetween HashSet<T> 无此 API
✅ 逆序遍历(Reverse() HashSet<T> 无内置逆序
✅ 接受 IComparer<T> 控制排序 HashSet<T> 使用 IEqualityComparer<T>

Stack

Queue

相关推荐
N***73852 小时前
ReactGraphQLAPI
大数据·c#·爬山算法
z***I3942 小时前
PHP Composer
开发语言·php·composer
1***81532 小时前
Swift在服务端开发的可能性探索
开发语言·ios·swift
2501_941879812 小时前
Python在微服务高并发异步流量控制与动态限流熔断架构中的实践
java·开发语言
lingxiao168882 小时前
WPF Prism框架应用
c#·wpf·prism
zero13_小葵司2 小时前
JavaScript性能优化系列(八)弱网环境体验优化 - 8.2 离线支持:Service Worker实现基本离线功能
开发语言·javascript·性能优化
S***H2832 小时前
Swift在系统级应用中的开发
开发语言·ios·swift
J***Q2922 小时前
Kotlin DSL开发技巧
android·开发语言·kotlin
E***U9452 小时前
Kotlin注解处理器
java·开发语言·kotlin