zoukankan      html  css  js  c++  java
  • (转) C#解惑:HashSet<T>类

    HashSet<T>是一个相对“冷门”的类型,平时在项目中用得不多,但是在特定的业务中可以大用。

    先来了解下HashSet<T>类,主要被设计用来存储集合,做高性能集运算,例如两个集合求交集、并集、差集等。从名称可以看出,它是基于Hash的,可以简单理解为没有Value的Dictionary。

    HashSet<T>不能用索引访问,不能存储重复数据,元素T必须正确实现了EqualsGetHashCode

    HashSet<T>的一些特性如下:

    1. HashSet<T>中的值不能重复且没有顺序。
    2. HashSet<T>的容量会按需自动添加。

    HashSet<T>的优势和与List<T>的比较

    HashSet<T>最大的优势是检索的性能,简单的说它的Contains方法的性能在大数据量时比List<T>好得多。曾经做过一个测试,将800W条int类型放在List<int>集合中,使用Contains判断是否存在,速度巨慢,而放在HashSet<int>性能得到大幅提升。

    在内部算法实现上,HashSet<T>的Contains方法复杂度是O(1),List<T>的Contains方法复杂度是O(n),后者数据量越大速度越慢,而HashSet<T>不受数据量的影响。

    所以在集合的目的是为了检索的情况下,我们应该使用HashSet<T>代替List<T>。比如一个存储关键字的集合,运行的时候通过其Contains方法检查输入字符串是否关键字。

    在3.5之前,想用哈希表来提高集合的查询效率,只有Hashtable和Dictionary两种选择,而这两种都是键-值方式的存储。但有些时候,我们只需要其中一个值,例如一个Email集合,如果用泛型哈希表来存储,往往要在Key和Value各保存一次,不可避免的要造成内存浪费。而HashSet只保存一个值,更加适合处理这种情况。

    此外,HashSet的Add方法返回bool值,在添加数据时,如果发现集合中已经存在,则忽略这次操作,并返回false值。而Hashtable和Dictionary碰到重复添加的情况会直接抛出错误。

    从使用上来看,HashSet和线性集合List更相似一些,但前者的查询效率有着极大的优势。假如,用户注册时输入邮箱要检查唯一性,而当前已注册的邮箱数量达到10万条,如果使用List进行查询,需要遍历一次列表,时间复杂度为O(n),而使用HashSet则不需要遍历,通过哈希算法直接得到列表中是否已存在,时间复杂度为O(1),这是哈希表的查询优势。

    和List的区别

    HashSet是Set集合,它只实现了ICollection接口,在单独元素访问上,有很大的限制:

    跟List相比,不能使用下标来访问元素,如:list[1] 。

    跟Dictionary相比,不能通过键值来访问元素,例如:dic[key],因为HashSet每条数据只保存一项,并不采用Key-Value的方式,换句话说,HashSet中的Key就是Value,假如已经知道了Key,也没必要再查询去获取Value,需要做的只是检查值是否已存在。

    所以剩下的仅仅是开头提到的集合操作,这是它的缺点,也是特点。

    集合运算

    IntersectWith (IEnumerable other) (交集)

    1.  
      public void IntersectWithTest()
    2.  
      {
    3.  
      HashSet<int> set1 = new HashSet<int>() { 1, 2, 3 };
    4.  
      HashSet<int> set2 = new HashSet<int>() { 2, 3, 4 };
    5.  
       
    6.  
      set1.IntersectWith(set2);
    7.  
       
    8.  
      foreach (var item in set1)
    9.  
      {
    10.  
      Console.WriteLine(item);
    11.  
      }
    12.  
       
    13.  
      //输出:2,3
    14.  
      }

    UnionWith (IEnumerable other) (并集)

    public void UnionWithTest()
    {
    HashSet set1 = new HashSet() { 1, 2, 3 };
    HashSet set2 = new HashSet() { 2, 3, 4 };

    1.  
      set1.UnionWith(set2);
    2.  
       
    3.  
      foreach (var item in set1)
    4.  
      {
    5.  
      Console.WriteLine(item);
    6.  
      }
    7.  
       
    8.  
      //输出:1,2,3,4
    9.  
      }

    ExceptWith (IEnumerable other) (排除)

    public void ExceptWithTest()
    {
    HashSet set1 = new HashSet() { 1, 2, 3 };
    HashSet set2 = new HashSet() { 2, 3, 4 };

    1.  
      set1.ExceptWith(set2);
    2.  
       
    3.  
      foreach (var item in set1)
    4.  
      {
    5.  
      Console.WriteLine(item);
    6.  
      }
    7.  
       
    8.  
      //输出:1
    9.  
      }
    原贴: https://blog.csdn.net/X_X_OO/article/details/52529548
  • 相关阅读:
    Python 集合
    Python sorted()
    CodeForces 508C Anya and Ghosts
    CodeForces 496B Secret Combination
    CodeForces 483B Friends and Presents
    CodeForces 490C Hacking Cypher
    CodeForces 483C Diverse Permutation
    CodeForces 478C Table Decorations
    CodeForces 454C Little Pony and Expected Maximum
    CodeForces 313C Ilya and Matrix
  • 原文地址:https://www.cnblogs.com/refuge/p/9465466.html
Copyright © 2011-2022 走看看