有人知道在C#中是否有与Java Set
集合相当的好处吗?我知道您可以使用Dictionary
或HashTable
通过填充但忽略值来模仿集合,但这不是一种非常优雅的方式。
答案 0 :(得分:402)
如果您使用的是.NET 3.5,则可以使用HashSet<T>
。确实,.NET不像Java那样适应集合。
Wintellect PowerCollections也可能有所帮助。
答案 1 :(得分:115)
HashSet<T>
数据结构:
.NET Framework 3.5中引入了Framework类库的HashSet<T>
数据结构。可以在MSDN reference page for HashSet<T>
找到其成员的完整列表。
HashSet<T>
或多或少是在mathematical set之后建模的,这意味着:
它可能不包含重复值。
其元素没有特别的顺序;因此,类型不实现IList<T>
接口,而是更基本的ICollection<T>
。因此,哈希集内的元素不能通过索引随机访问;它们只能通过枚举器进行迭代。
某些设置功能可用,例如Union
,Intersection
,IsSubsetOf
,IsSupersetOf
。当使用多组时,这些可以派上用场。
HashSet<T>
和List<T>
之间的另一个区别是调用哈希集的Add(item)
方法会返回一个布尔值:true
如果项目已添加,{{1}否则(因为它已经在集合中找到)。
为什么不false
?
由于List<T>
只是一个唯一对象的集合,您可能想知道为什么它必须是一个数据结构。普通HashSet<T>
可以通过在添加之前检查列表中是否找到对象来具有相同的行为。
简短的回答是速度。随着更多元素的添加,正常List<T>
搜索变得非常慢。 List<T>
需要一种结构设计,以便快速搜索和插入。
<强>基准:强>
让我们比较HashSet<T>
与HashSet<T>
的效果速度。
每个试验包括为每个集合添加0到9,999的整数。但是,mod 25适用于每个整数。 Mod 25生成最大类型的项目25.由于添加了10,000个元素,因此强制发生400次冲突,使数据结构有机会使用其搜索算法。在10,000次试验后测量3次并取平均值。
不要过多关注测试的具体运行时间,因为它们取决于我的硬件,但看看它们是如何相互比较的。
List<T>
现在让我们创建元素对象而不是基本类型。我写了一个包含三个字段的快速 Average time [ms]
----------------------------
HashSet<T> 2,290
List<T> 5,505
课程:Person
,Name
和LastName
。由于我没有包含任何比较对象的特定方法,因此将添加所有元素而不会发生冲突。这次,为每次试验添加了1,000 ID
个对象。平均3组1000次试验的总次数。
Person
如您所见,使用对象时,运行时间的差异变得天文数字,使 Average time [ms]
----------------------------
HashSet<Person> 201
List<Person> 3,000
变得有利。
答案 2 :(得分:106)
尝试HashSet:
HashSet(Of T)类提供高性能的集合操作。集合是一个不包含重复元素的集合,其元素没有特定的顺序......
HashSet(Of T)对象的容量是对象可以容纳的元素数。当元素添加到对象时,HashSet(Of T)对象的容量会自动增加。
HashSet(Of T)类基于数学集模型,提供类似于访问Dictionary(Of TKey, TValue)或Hashtable集合的键的高性能集合操作。简单来说,HashSet(Of T)类可以被认为是没有值的Dictionary(Of TKey, TValue)集合。
HashSet(Of T)集合未排序且不能包含重复元素...
答案 3 :(得分:18)
如果您使用的是.NET 4.0或更高版本:
如果您需要排序,请使用SortedSet<T>
。否则,如果不这样做,则使用HashSet<T>
,因为O(1)
用于搜索和操作操作。而SortedSet<T>
为O(log n)
用于搜索和操作操作。
答案 4 :(得分:14)
我使用Iesi.Collections http://www.codeproject.com/KB/recipes/sets.aspx
它在许多OSS项目中使用,我首先在NHibernate中看到它
答案 5 :(得分:12)
我在Dictionary<T, object>
周围使用包装器,在值中存储空值。这使得O(1)在键上添加,查找和删除,并且所有意图和目的都像集合一样。
答案 6 :(得分:11)
在CodePlex上查看PowerCollections。除了Set和OrderedSet之外,它还有一些其他有用的集合类型,如Deque,MultiDictionary,Bag,OrderedBag,OrderedDictionary和OrderedMultiDictionary。
对于更多收藏品,还有C5 Generic Collection Library。
答案 7 :(得分:0)
您可以在几个小时内实现自己的可行集实现。我必须这样做时使用了这个(对不起,我没有方便的代码):http://java.sun.com/j2se/1.4.2/docs/api/java/util/Set.html
答案 8 :(得分:-5)
我知道这是一个旧线程,但我遇到了同样的问题,发现HashSet非常不可靠,因为给定相同的种子,GetHashCode()返回不同的代码。所以,我想,为什么不使用List并隐藏像这样的添加方法
public class UniqueList<T> : List<T>
{
public new void Add(T obj)
{
if(!Contains(obj))
{
base.Add(obj);
}
}
}
因为List仅使用Equals方法来确定相等性,所以可以在T类型上定义Equals方法以确保获得所需的结果。