寻求可自动排序且支持数据访问的C#键值对结构
嘿,我完全懂你的困扰——既要像SortedSet那样自动帮你排好序,又要保留List那样按索引访问的能力,基础集合里确实找不到直接匹配的,但咱们可以通过组合现有结构或者封装自定义集合来解决,针对你10万节点的场景,这几个方案都很靠谱:
方案1:双集合同步维护
这是最直接的思路,用两个集合分别承担不同的职责:
- 用
List<T>保留节点的添加顺序,你可以完全按照原来的逻辑用索引访问、修改,这个列表的索引就代表添加历史,绝对不碰排序逻辑; - 用
SortedSet<T>(如果你的节点实现了IComparable<T>接口)或者SortedDictionary<TSortKey, T>(用你需要排序的属性作为Key)来维护自动排序的视图。
操作的时候只要同步两个集合就行:
- 添加节点:先把节点加入
List,再插入到排序集合里; - 修改节点:如果修改的是不影响排序的属性,直接在
List里改对应索引的元素就行;如果修改的是排序相关的属性,要先从排序集合里移除旧节点,更新后再重新添加进去,同时同步List里的元素。
这个方案的优势是完全用基础集合实现,不用额外依赖,10万级别的数据量下,SortedSet/SortedDictionary的O(log n)增删查性能完全够用。
方案2:封装自定义集合类
把刚才的双集合逻辑封装成一个自定义类,对外只暴露你需要的接口,这样外部调用的时候不用操心同步问题,代码更整洁。比如用C#写个简单的示例(看你提到SortedSet,应该是.NET环境):
public class OrderedSortedCollection<T> where T : IComparable<T> { // 维护添加顺序的列表 private readonly List<T> _orderedItems = new List<T>(); // 维护自动排序的集合 private readonly SortedSet<T> _sortedItems = new SortedSet<T>(); // 添加节点 public void Add(T item) { _orderedItems.Add(item); _sortedItems.Add(item); } // 按索引访问/修改节点 public T this[int index] { get => _orderedItems[index]; set { var oldItem = _orderedItems[index]; // 先移除排序集合里的旧节点 _sortedItems.Remove(oldItem); // 更新顺序列表 _orderedItems[index] = value; // 把新节点加入排序集合 _sortedItems.Add(value); } } // 获取排序后的所有节点 public IEnumerable<T> GetSortedItems() => _sortedItems; }
使用的时候,你就可以像用List一样按索引操作,同时通过GetSortedItems()拿到自动排序的结果。如果你的节点排序逻辑不是基于自身的IComparable,还可以给SortedSet传自定义的IComparer<T>来实现自定义排序规则。
一些优化小建议
- 如果你的修改操作里,排序属性的变更很频繁,
SortedSet的移除+添加是O(log n),性能没问题;如果是极端高频的中间位置增改,可以考虑换成SortedList<TKey, TValue>,它的随机访问更快,但中间插入删除是O(n),要根据你的实际业务场景选择; - 如果节点有重复的排序属性,
SortedSet会自动去重,这时候你可以用SortedDictionary并结合自定义比较器,或者给节点加唯一标识来处理重复值。
内容的提问来源于stack exchange,提问作者crapolantern
相关产品推荐
相关产品推荐

