C# 排序列表SortedList使用方法 C# SortedList是如何工作的

来源:这里教程网 时间:2026-02-21 17:40:41 作者:

SortedList 添加元素时,键重复会怎样?

直接抛异常——

Add(key, value)
不允许重复键。这是和
Dictionary
最关键的区别之一:Dictionary 允许用索引器赋值(
dict[key] = value
)来覆盖,而
Add
方法在键已存在时会立即 throw
ArgumentException

想安全更新?用索引器赋值:
sortedList[key] = newValue
,它会插入新项或替换旧值
想先判断再加?用
ContainsKey(key)
配合
Add
,但注意这不是原子操作,多线程下仍可能竞态
泛型版本要求
TKey
实现
IComparable<tkey></tkey>
(如
int
string
默认支持),否则运行时报错

为什么遍历时总是按键升序?内部是怎么维持排序的?

SortedList
不是靠每次遍历排序,而是「插入即排序」——它内部用两个平行数组(一个存键、一个存值),每次
Add
都用二分查找定位插入位置,然后挪动后续元素腾出空位。所以:

查找是
O(log n)
,比
Dictionary
O(1)
慢;但遍历是
O(n)
且天然有序,不用额外
OrderBy
索引访问(如
GetByIndex(2)
Keys[2]
)是真·数组下标,不是哈希映射——所以
IndexOfKey("abc")
返回的是排序后的位置,不是原始插入顺序
删掉中间一项(
RemoveAt(5)
)会导致后面所有索引前移,这点容易在循环中误用导致跳项或越界

Keys 和 Values 属性返回的是什么?能直接修改吗?

Keys
Values
返回的是只读视图(
IReadOnlyCollection<tkey></tkey>
/
IReadOnlyCollection<tvalue></tvalue>
),不是副本。它们反映当前排序状态,但本身不可写。

不能对
Keys
调用
Add
Clear
——会报
NotSupportedException
遍历时可放心用
foreach (var k in sortedList.Keys)
,性能好且顺序确定
若需独立副本(比如要排序后再改),得显式转成列表:
new List<string>(sortedList.Keys)</string>

什么时候该选 SortedList,而不是 Dictionary 或 Listair>>?

核心看需求是否「既要按 key 快速查,又要按顺序遍历/取范围」。例如实现 LRU 缓存、时间序列配置表、带序号的配置项映射。

需要频繁
GetByIndex(i)
GetKey(i)
取第 N 个元素?选
SortedList
Dictionary
不支持索引访问
数据量小(SortedList 省去手动排序开销 写入频繁(尤其随机插入)、又不关心遍历顺序?
Dictionary
更快;
SortedList
插入平均
O(n)
(因数组搬移)

别忽略容量细节:

TrimToSize()
能释放冗余内存,但调用后下次扩容又会重新分配——高频增删场景慎用。

相关推荐