我正在寻找.Net类,它基本上可以:
- 确保其中的项目是唯一的(如哈希集)
- 确保在枚举时,我们获取的项目顺序与插入它们的顺序相同(如列表)
是否有现有的 .Net 类可以执行此操作?
我知道HashSet
(不能保证顺序),SortedSet
(内容上的顺序),但它们不符合我的需求。我没有任何其他需求(如Stack
或Queue
)。
我目前的替代方案是在添加和删除数据之前有一个List<>
并使用Contains(...)
。
你是对的。哈希集不保留广告顺序。
Stackoverflow:HashSet,保留了achitaka-san的排序它使用字典查找项目,使用链接列表来保持顺序。所有三个插入、删除和查找工作仍在 O(1) 中。
public class OrderedSet<T> : ICollection<T>
{
private readonly IDictionary<T, LinkedListNode<T>> m_Dictionary;
private readonly LinkedList<T> m_LinkedList;
public OrderedSet()
: this(EqualityComparer<T>.Default)
{
}
public OrderedSet(IEqualityComparer<T> comparer)
{
m_Dictionary = new Dictionary<T, LinkedListNode<T>>(comparer);
m_LinkedList = new LinkedList<T>();
}
public int Count
{
get { return m_Dictionary.Count; }
}
public virtual bool IsReadOnly
{
get { return m_Dictionary.IsReadOnly; }
}
void ICollection<T>.Add(T item)
{
Add(item);
}
public bool Add(T item)
{
if (m_Dictionary.ContainsKey(item)) return false;
LinkedListNode<T> node = m_LinkedList.AddLast(item);
m_Dictionary.Add(item, node);
return true;
}
public void Clear()
{
m_LinkedList.Clear();
m_Dictionary.Clear();
}
public bool Remove(T item)
{
LinkedListNode<T> node;
bool found = m_Dictionary.TryGetValue(item, out node);
if (!found) return false;
m_Dictionary.Remove(item);
m_LinkedList.Remove(node);
return true;
}
public IEnumerator<T> GetEnumerator()
{
return m_LinkedList.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public bool Contains(T item)
{
return m_Dictionary.ContainsKey(item);
}
public void CopyTo(T[] array, int arrayIndex)
{
m_LinkedList.CopyTo(array, arrayIndex);
}
}
另一种实现:
@Codeproject:保留插入顺序的哈希集或链接哈希集的 .NET 实现
OrderedDictionary
,文档可以在这里找到
您将使用当前List
中的值作为字典中的键,并且可以将值保留为一些随机性。
OrderedDictionary myOrderedDictionary = new OrderedDictionary();
myOrderedDictionary.Add(1, "smth");
myOrderedDictionary.Add(2, "smth");
foreach (DictionaryEntry v in myOrderedDictionary)
{
int youValue = (int)v.Key;
}
这里唯一的缺点是这本字典不使用泛型,你必须自己object
投。