C#中的SortedSet是System.Collections.Generic命名空间下的一个泛型集合类,它的核心特点是会对添加的元素自动进行排序,并且保证集合内的元素不会重复,非常适合需要有序无重复数据的业务场景。

SortedSet基础特性
SortedSet的排序规则默认遵循元素的自然排序顺序,对于数值类型会按从小到大排列,对于字符串会按字典序排列。如果添加重复元素,集合不会报错,但是会直接忽略该元素,不会将其加入集合中。
使用前需要先引入对应的命名空间:
using System.Collections.Generic;
常用操作方法
创建与添加元素
创建SortedSet后可以通过Add方法添加元素,添加后会自动触发排序逻辑:
// 创建存储整数的SortedSet
SortedSet<int> numberSet = new SortedSet<int>();
// 添加元素
numberSet.Add(5);
numberSet.Add(2);
numberSet.Add(8);
numberSet.Add(2); // 重复元素,不会被加入集合
// 遍历输出,会自动按从小到大顺序展示
foreach (int num in numberSet)
{
Console.WriteLine(num);
}
// 输出结果:2 5 8
删除与查找元素
SortedSet提供了Remove方法删除指定元素,Contains方法判断元素是否存在:
SortedSet<string> nameSet = new SortedSet<string>();
nameSet.Add("张三");
nameSet.Add("李四");
nameSet.Add("王五");
// 判断元素是否存在
bool hasLi = nameSet.Contains("李四"); // 返回true
// 删除元素
bool isRemoved = nameSet.Remove("张三"); // 返回true,删除成功
// 遍历剩余元素,按字典序排列
foreach (string name in nameSet)
{
Console.WriteLine(name);
}
// 输出结果:李四 王五
获取子集与范围操作
SortedSet支持获取指定范围内的子集,通过GetViewBetween方法实现:
SortedSet<int> scoreSet = new SortedSet<int> { 60, 75, 82, 90, 95 };
// 获取分数在70到90之间的子集(包含边界值)
SortedSet<int> subSet = scoreSet.GetViewBetween(70, 90);
foreach (int score in subSet)
{
Console.WriteLine(score);
}
// 输出结果:75 82 90
与其他集合的对比
为了更清晰了解SortedSet的适用场景,我们将其和常见的集合做简单对比:
| 集合类型 | 是否排序 | 是否允许重复 | 典型适用场景 |
|---|---|---|---|
| List<T> | 否 | 是 | 需要按顺序存储可重复元素的场景 |
| HashSet<T> | 否 | 否 | 只需要去重不需要排序的场景 |
| SortedSet<T> | 是 | 否 | 需要去重且自动排序的场景 |
自定义排序规则
如果默认排序规则不符合需求,可以在创建SortedSet时传入自定义的比较器,比如让整数按从大到小排序:
// 自定义比较器,实现从大到小排序
class DescComparer : IComparer<int>
{
public int Compare(int x, int y)
{
// 反转默认比较结果即可实现降序
return y.CompareTo(x);
}
}
// 使用自定义比较器创建SortedSet
SortedSet<int> descSet = new SortedSet<int>(new DescComparer());
descSet.Add(3);
descSet.Add(1);
descSet.Add(7);
foreach (int num in descSet)
{
Console.WriteLine(num);
}
// 输出结果:7 3 1
使用注意事项
- SortedSet的元素类型必须实现
IComparable<T>接口,否则无法完成自动排序,自定义类型需要手动实现该接口或者传入自定义比较器。 - 添加、删除、查找操作的时间复杂度都是O(log n),相比HashSet的O(1)会稍高,所以如果是只需要去重不需要排序的场景,优先选择HashSet。
- GetViewBetween方法返回的是原集合的视图,修改视图会影响原集合,修改原集合也会影响视图,使用时需要注意数据的联动变化。