可观察对象顺序在.net中设置
本文关键字:net 设置 顺序 观察 对象 | 更新日期: 2023-09-27 18:12:54
我需要一个按顺序排列的集合,就像一个列表。
集合也可以是可观察的。
任何建造。在。net 4中是这样的吗?
据我所知,在。net中没有这样的类型。我最近需要这个,并最终自己实现了它;没那么难。
技巧是将Dictionary<T, LinkedListNode<T>>
与LinkedList<T>
结合起来。使用字典在O(1)时间内查询键和值,并按插入顺序迭代列表。你需要一个字典而不是一个集合,因为你想要能够调用LinkedList<T>.Remove(LinkedListNode<T>)
而不是LinkedList<T>.Remove(T)
。前者的时间复杂度为O(1),后者为O(n)。
听起来你需要ReadOnly Queue。在。net中,我们内置了Queue类,但是没有内置ReadOnly Queue。要确保没有重复的值,可以使用contains check
有一个Nuget包具有ImmutableQueue。不确定它能不能帮到你。这将在每次Enqueue或Dequeue操作完成时创建新的Queue对象。https://msdn.microsoft.com/en-us/library/dn467186 (v = vs.111) . aspx
我想你可以使用SortedDictionary<>
和Dictionary<>
一起做这个。
假设您永远不会在集合中进行超过int.MaxValue
的插入,您可以使用整数"序列号"作为SortedDictionary
的键,以跟踪按插入顺序插入的项。
除此之外,您还需要使用Dictionary
将项目映射到用于插入它们的序列号。
把这些放到一个类和一个演示程序中:(不是线程安全的!)
using System;
using System.Collections;
using System.Collections.Generic;
namespace Demo
{
public sealed class SequencedSet<T>: IEnumerable<T>
{
private readonly SortedDictionary<int, T> items = new SortedDictionary<int, T>();
private readonly Dictionary<T, int> order = new Dictionary<T, int>();
private int sequenceNumber = 0;
public void Add(T item)
{
if (order.ContainsKey(item))
return; // Or throw if you want.
order[item] = sequenceNumber;
items[sequenceNumber] = item;
++sequenceNumber;
}
public void Remove(T item)
{
if (!order.ContainsKey(item))
return; // Or throw if you want.
int sequence = order[item];
items.Remove(sequence);
order.Remove(item);
}
public bool Contains(T item)
{
return order.ContainsKey(item);
}
public IEnumerator<T> GetEnumerator()
{
return items.Values.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
internal class Program
{
private static void Main()
{
var test = new SequencedSet<string>();
test.Add("One");
test.Add("Two");
test.Add("Three");
test.Add("Four");
test.Add("Five");
test.Remove("Four");
test.Remove("Two");
foreach (var item in test)
Console.WriteLine(item);
}
}
}
对于插入和删除来说,这应该是相当高效的,但它当然会占用两倍的内存。如果你要做大量的插入和删除,你可以使用long
而不是int
作为序列号。
不幸的是,如果你做了超过2^63的删除,即使这将不起作用-尽管我认为这应该是足够的…