C# 是否存在这样的集合(字典和哈希集的功能)?
我正在寻找一个集合,其中没有任何元素可以存在一次以上,并且也被索引。类似于C# 是否存在这样的集合(字典和哈希集的功能)?,c#,list,dictionary,collections,hashset,C#,List,Dictionary,Collections,Hashset,我正在寻找一个集合,其中没有任何元素可以存在一次以上,并且也被索引。类似于字典,但没有键,只有值。类似于HashSet,但已编制索引,因此我可以轻松检索元素,而无需迭代集合。我希望这是有道理的 您可以使用哈希集。它是“索引”的,毕竟,如果没有索引,性能将是缺乏的 使用该方法“检索”元素。如果您也要删除它,请使用 这两种方法都是O(1)运算。您可以使用字典,并使用Add(value,value)插入元素 但是,只有当您的类型正确地实现了Equals(object)和GetHashCode()时,这
字典
,但没有键,只有值。类似于HashSet
,但已编制索引,因此我可以轻松检索元素,而无需迭代集合。我希望这是有道理的 您可以使用哈希集
。它是“索引”的,毕竟,如果没有索引,性能将是缺乏的
使用该方法“检索”元素。如果您也要删除它,请使用
这两种方法都是O(1)运算。您可以使用
字典
,并使用Add(value,value)
插入元素
但是,只有当您的类型正确地实现了
Equals(object)
和GetHashCode()
时,这才有意义。否则,两个不同的实例将永远不相等,HashSet
的包含(t)
方法已经告诉您是否具有nor的元素引用。HashSet类最适合您的工作。我不允许重复输入。
请注意,如果项目被添加到集合中,HashSet.Add(T item)方法将返回一个bool--truefalse如果项目已存在
只需添加一个扩展方法即可作为异常抛出
public static void AddOrThrow<T>(this HashSet<T> hash, T item)
{
if (!hash.Add(item))
throw new ValueExistingException();
}
publicstaticvoidaddorthrow(此哈希集散列,T项)
{
如果(!hash.Add(项))
抛出新值existingexception();
}
最简单的方法是创建一个实现IList
但在内部使用列表和哈希集的类。然后,您只需让每个方法根据需要对每个集合进行操作
using System;
using System.Collections.Generic;
namespace Example
{
public class UniqueList<T> : IList<T>
{
private readonly List<T> _list;
private readonly HashSet<T> _hashset;
public UniqueList()
{
_list = new List<T>();
_hashset = new HashSet<T>();
}
public UniqueList(IEqualityComparer<T> comparer)
{
_list = new List<T>();
_hashset = new HashSet<T>(comparer);
}
void ICollection<T>.Add(T item)
{
Add(item);
}
public bool Add(T item)
{
var added = _hashset.Add(item);
if (added)
{
_list.Add(item);
}
return added;
}
public void RemoveAt(int index)
{
_hashset.Remove(_list[index]);
_list.RemoveAt(index);
}
public T this[int index]
{
get { return _list[index]; }
set
{
var oldItem = _list[index];
_hashset.Remove(oldItem);
var added = _hashset.Add(value);
if (added)
{
_list[index] = value;
}
else
{
//Put the old item back before we raise a exception.
_hashset.Add(oldItem);
throw new InvalidOperationException("Object already exists.");
}
}
}
public int IndexOf(T item)
{
return _list.IndexOf(item);
}
void IList<T>.Insert(int index, T item)
{
Insert(index, item);
}
public bool Insert(int index, T item)
{
var added = _hashset.Add(item);
if (added)
{
_list.Insert(index, item);
}
return added;
}
public void Clear()
{
_list.Clear();
_hashset.Clear();
}
public bool Contains(T item)
{
return _hashset.Contains(item);
}
public void CopyTo(T[] array, int arrayIndex)
{
_list.CopyTo(array, arrayIndex);
}
public bool IsReadOnly
{
get { return false; }
}
public bool Remove(T item)
{
var removed = _hashset.Remove(item);
if (removed)
{
_list.Remove(item);
}
return removed;
}
public int Count
{
get { return _list.Count; }
}
public IEnumerator<T> GetEnumerator()
{
return _list.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}
使用系统;
使用System.Collections.Generic;
名称空间示例
{
公共类唯一列表:IList
{
私有只读列表_List;
私有只读哈希集\u哈希集;
公共唯一列表()
{
_列表=新列表();
_hashset=新的hashset();
}
公共唯一列表(IEqualityComparer比较器)
{
_列表=新列表();
_hashset=新的hashset(比较器);
}
作废ICollection.Add(T项)
{
增加(项目);
}
公共布尔添加(T项)
{
var added=\u hashset.Add(项);
如有(新增)
{
_列表。添加(项目);
}
增加了退货;
}
公共无效删除(整数索引)
{
_删除(_list[index]);
_列表。删除(索引);
}
公共T此[int索引]
{
获取{return _list[index];}
设置
{
var oldItem=_列表[索引];
_hashset.Remove(oldItem);
var added=\u hashset.Add(值);
如有(新增)
{
_列表[索引]=值;
}
其他的
{
//在引发异常之前,请将旧项目放回原处。
_hashset.Add(oldItem);
抛出新的InvalidOperationException(“对象已存在”);
}
}
}
公共整数索引(T项)
{
返回(项目)的列表索引;
}
void IList.Insert(整型索引,T项)
{
插入(索引,项目);
}
公共布尔插入(整数索引,T项)
{
var added=\u hashset.Add(项);
如有(新增)
{
_列表。插入(索引,项目);
}
增加了退货;
}
公共空间清除()
{
_list.Clear();
_Clear();
}
公共布尔包含(T项)
{
返回_hashset.Contains(项);
}
public void CopyTo(T[]数组,int arrayIndex)
{
_CopyTo(数组,arrayIndex);
}
公共图书馆是只读的
{
获取{return false;}
}
公共布尔删除(T项)
{
var removed=\u hashset.Remove(项);
如果(已删除)
{
_列表。删除(项目);
}
移除返回;
}
公共整数计数
{
获取{return\u list.Count;}
}
公共IEnumerator GetEnumerator()
{
返回_list.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
返回GetEnumerator();
}
}
}
我做了Add
和Insert
的显式实现,这样我可以给他们返回bool
的版本来判断操作是否成功。我无法在T此[int index]
setter中返回值,因此如果您尝试插入重复项,我会让它抛出invalidoOperationException
如果您执行ICollection.Add
对副本执行操作,它不会抛出。它只是不添加副本。这是因为这是HashSet.ICollection.Add的行为,我想模仿它。取决于你对“索引”的定义,你能更详细地说明你将如何使用所述索引吗?如果你想检索hash集中的实际对象,如果给定另一个与之相等的对象,那么这没有帮助。