--HashSet<T>)
.Net3.5之后出现了HashSetT硬翻译过来就是“哈希集合”跟“哈希”两字挂钩说明这种集合的内部实现用到了哈希算法用Reflector工具就可以发现HashSetT和DictionaryTKey,TValue使用了相同的存储方式和哈希冲突算法那么它跟DictionaryTKey,TValue和Hashtable在使用上到底有什么不同HashSetT对集合运算的操作HashSetT是一个Set集合虽然List、Collection也叫集合但Set集合和它们却大有不同。HashSetT提供了和“Set集合运算”相关的方法如IntersectWith(IEnumerableT other) 交集public void IntersectWithTest() { HashSetint set1 new HashSetint() { 1, 2, 3 }; HashSetint set2 new HashSetint() { 2, 3, 4 }; set1.IntersectWith(set2); foreach (var item in set1) { Console.WriteLine(item); } //输出2,3 }UnionWith(IEnumerableT other) 并集public void UnionWithTest() { HashSetint set1 new HashSetint() { 1, 2, 3 }; HashSetint set2 new HashSetint() { 2, 3, 4 }; set1.UnionWith(set2); foreach (var item in set1) { Console.WriteLine(item); } //输出1,2,3,4 }ExceptWith(IEnumerableT other) 排除public void ExceptWithTest() { HashSetint set1 new HashSetint() { 1, 2, 3 }; HashSetint set2 new HashSetint() { 2, 3, 4 }; set1.ExceptWith(set2); foreach (var item in set1) { Console.WriteLine(item); } //输出1 }这些对集合的操作是ListT、Hashtable和DictionaryTKey,TValue所缺少的但是伴随着Linq和扩展方法的出现.net 3.5为泛型集合提供了一系列的扩展方法使得所有的泛型集合具备了set集合操作的能力。例如与HashSet的IntersectWith 方法对应的扩展方法是IEnumerableT 的Intersect两者的区别是HashSetT.IntersectWith 是对当前集合进行修改没有返回值IEnumerableT.Intersect并不修改原集合而是返回了一个新的集合。实例代码如下public void IntersectTest() { HashSetint set1 new HashSetint() { 1, 2, 3 }; HashSetint set2 new HashSetint() { 2, 3, 4 }; IEnumerableint set3set1.Intersect(set2); foreach (var item in set1) { Console.WriteLine(item); } foreach (var item in set3) { Console.WriteLine(item); } //输出o //set1 : 1,2,3 //set3 : 2,3 }IEnumerableT 其他的扩展方法也是一样都是不改变调用方法的数组而是产生并返回新的IEnumerableT接口类型的数组当然你可以通过ToArray,ToList,ToDictionary将返回值转换成你想要的集合类型。至于如何使用这两种集合操作方式要取决于你的习惯和业务需求。HashSetT的特点在3.5之前想用哈希表来提高集合的查询效率只有Hashtable和DictionaryTKey,TValue两种选择而这两种都是键-值方式的存储。但有些时候我们只需要其中一个值例如一个Email集合如果用泛型哈希表来存储往往要在Key和Value各保存一次不可避免的要造成内存浪费。而HashSetT只保存一个值更加适合处理这种情况。此外HashSetT的Add方法返回bool值在添加数据时如果发现集合中已经存在则忽略这次操作并返回false值。而Hashtable和DictionaryTKey,TValue碰到重复添加的情况会直接抛出错误。从使用上来看HashSetT和线性集合ListT更相似一些但前者的查询效率有着极大的优势。假如用户注册时输入邮箱要检查唯一性而当前已注册的邮箱数量达到10万条如果使用ListT进行查询需要遍历一次列表时间复杂度为On而使用HashSetT则不需要遍历通过哈希算法直接得到列表中是否已存在时间复杂度为O1这是哈希表的查询优势在上一篇中已提到。HashSetT的不能做的事情HashSetT是Set集合它只实现了ICollection接口在单独元素访问上有很大的限制跟ListT相比不能使用下标来访问元素如list[1] 。跟DictionaryTKey,TValue相比不能通过键值来访问元素例如dic[key]因为HashSetT每条数据只保存一项并不采用Key-Value的方式换句话说HashSetT中的Key就是Value假如已经知道了Key也没必要再查询去获取Value需要做的只是检查值是否已存在。所以剩下的仅仅是开头提到的集合操作这是它的缺点也是特点。总结综上可知HashSetT是一个Set集合查询上有较大优势但无法通过下标方式来访问单个元素这点会让用惯了ListT的人我就是用起来很不顺手。HashSetT有别于其他哈希表具有很多集合操作的方法但优势并不明显因为.net 3.5之后扩展方法赋予了泛型集合进行集合操作的能力但扩展方法的集合操作往往返回新的集合在使用习惯上我个人更偏爱HashSetT的操作方式。