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()能释放冗余内存,但调用后下次扩容又会重新分配——高频增删场景慎用。
