zoukankan      html  css  js  c++  java
  • 转载 HashSet用法 合交并差

    NET 3.5在System.Collections.Generic命名空间中包含一个新的集合类:HashSet<T>。这个集合类包含不重复项的无序列表。这种集合称为“集(set)”。集是一个保留字,所以该类有另一个名称HashSet<T>。这个名称很容易理解,因为这个集合基于散列值,插入元素的操作非常快,不需要像List<T>类那样重排集合。

    HashSet<T>类提供的方法可以创建合集和交集。表1列出了改变集的值的方法。

    表1

    HashSet<T>的修改方法 说    明
    Add() 如果某元素不在集合中,Add()方法就把该元素添加到集合中。在其返回值Boolean中,返回元素是否添加的信息
    Clear() 方法Clear()删除集合中的所有元素
    Remove() Remove()方法删除指定的元素
    RemoveWhere() RemoveWhere()方法需要一个Predicate<T>委托作为参数。删除满足谓词条件的所有元素
    CopyTo()   CopyTo()把集合中的元素复制到一个数组中
    ExceptWith() ExceptWith()方法把一个集合作为参数,从集中删除该集合中的所有元素
    IntersectWith() IntersectWith()修改了集,仅包含所传送的集合和集中都有的元素
    UnionWith()   UnionWith()方法把传送为参数的集合中的所有元素添加到集中

    表2列出了仅返回集的信息、不修改元素的方法。

    HashSet<T>的验证方法 说明
    Contains() 如果所传送的元素在集合中,方法Contains()就返回true
    IsSubsetOf() 如果参数传送的集合是集的一个子集,方法IsSubsetOf()就返回true
    IsSupersetOf() 如果参数传送的集合是集的一个超集,方法IsSupersetOf()就返回true
    Overlaps() 如果参数传送的集合中至少有一个元素与集中的元素相同,Overlaps()就返回true
    SetEquals() 如果参数传送的集合和集包含完全相同的元素,方法SetEquals()就返回true

    在示例代码中,创建了3个字符串类型的新集,并用一级方程式汽车填充。HashSet<T>类实现了ICollection<T>接口。但是在该类中,Add()方法是显式实现的。Add()方法的区别是返回类型,它返回一个布尔值,说明是否添加了元素。如果该元素已经在集中,就不添加它,并返回false。

    复制代码
    HashSet < string > companyTeams =new HashSet < string > (){ "Ferrari", "McLaren", "Toyota", "BMW","Renault", "Honda" };
    
    HashSet < string > traditionalTeams =new HashSet < string > (){ "Ferrari", "McLaren" };
    
    HashSet < string > privateTeams =new HashSet < string > (){ "Red Bull", "Toro Rosso", "Spyker","Super Aguri" };
    
    if (privateTeams.Add("Williams"))
        Console.WriteLine("Williams added");
    if (!companyTeams.Add("McLaren"))
        Console.WriteLine("McLaren was already in this set");
    复制代码

    两个Add()方法的输出写到控制台上:

    Williams added

    McLaren was already in this set

    方法IsSubsetOf()和IsSupersetOf()比较集和实现了IEnumerable<T>接口的集合,返回一个布尔结果。这里,IsSubsetOf()验证traditionalTeams中的每个元素是否都包含在companyTeams中,IsSupersetOf()验证companyTeams 是否是traditionalTeams的超集。

    复制代码
    if (traditionalTeams.IsSubsetOf(companyTeams))
    {
      Console.WriteLine("traditionalTeams is " +"subset of companyTeams");
    }
    
    if (companyTeams.IsSupersetOf(traditionalTeams))
    {
      Console.WriteLine("companyTeams is a superset of " +"traditionalTeams");
    }
    复制代码

    这个验证的结果如下:

    traditionalTeams is a subset of companyTeams

    companyTeams is a superset of traditionalTeams

    Williams也是一个传统队,因此这个队添加到traditionalTeams集合中:

    traditionalTeams.Add("Williams");//前面代码中privateTeams已经加入该元素
    if (privateTeams.Overlaps(traditionalTeams))
    {
        Console.WriteLine("At least one team is " +"the same with the traditional " +"and privateteams");
    }

    这有一个重叠,所以结果如下:

    At least one team is the same with the traditional and private teams.

    调用UnionWith()方法,给变量allTeams填充了companyTeams、PrivateTeams和traditionalTeams的合集:

    复制代码
    HashSet < string > allTeams =new HashSet < string > (companyTeams);
    allTeams.UnionWith(privateTeams);
    allTeams.UnionWith(traditionalTeams);
    Console.WriteLine();
    Console.WriteLine("all teams");
    foreach (var team in allTeams)
    {
       Console.WriteLine(team);
    }
    复制代码

    这里返回所有的队,但每个队都只列出一次,因为集只包含唯一值:

    Ferrari

    McLaren

    Toyota

    BMW

    Renault

    Honda

    Red Bull

    Toro Rosso

    Spyker

    Super Aguri

    Williams

    方法ExceptWith()从allTeams集中删除所有的私人队:

    复制代码
    allTeams.ExceptWith(privateTeams);
    Console.WriteLine();
    Console.WriteLine("no private team left");
    foreach (var team in allTeams)
    {
        Console.WriteLine(team);
    }
    复制代码

    集合中的其他元素不包含私人队:

    Ferrari

    McLaren

    Toyota

    BMW

    Renault

    Honda

    1.HashSet集合

    HashSet是以数学Set集合为基础的,使用HashSet可以提高集合的运算。使用HashSet集合不自带排序方法,如果需要排序的需求可以参考使用List<T>集合配合Sort方法。

    HashSet的优势在与运算快,作为一种存放在内存的数据,可以很快的进行设置和取值的操作。HashSet无法向里面添加重复的数据,避免添加HashSet<T>里面的数据重复。我们使用HashSet常常在集合相加集合相减这些集合与集合之间的操作之中。

    使用HashSet作为内存存储的快速数据库,这个需要随时跟新HashSet里面的数据,因为在HashSet中一个长时间未被访问的数据,将被系统自动回收掉,那么就会导致失败,那么如何才能保证HashSet里面的值是长存在的而且达到不断的更新里面的值呢?

    首先程序过来访问我们HashSet里面有没有需要的数据,如果有我们需要的数据就直接返回给用户,不用调用查询数据库的操作。如果HashSet里面没有我们需要的数据,程序再去查询一次数据库是否有该Query数据,如果有返回给用户同时把查询的结果添加到HashSet里面,这么做可以一定程度的降低查询数据库所带来的不便,但是不能根除,需要进一步提升性能,可以查看前面的缓存策略使用memcached来提高网站查询和访问。

    1.1.我们要求两个集合的并集

     
    HashSet<int> numbers1;
    HashSet<int> numbers2;
    //分别进行numbers1和numbers2的值初始化或赋值
    numbers1.UnionWith(numbers2);//求两个集合的并集。

    1.2.求两个集合的交集

    HashSet<int> numbers1;
    HashSet<int> numbers2;
    //分别进行numbers1和numbers2的值初始化或赋值
    numbers1.IntersectWith(numbers2);//求两个集合的交集。

    1.3.求两个集合的差集

     
    HashSet<int> numbers1;
    HashSet<int> numbers2;
    //分别进行numbers1和numbers2的值初始化或赋值
    numbers1.ExceptWith(numbers2);//求两个集合的差集。

    1.4.求两个集合的对称差集

     
    HashSet<int> numbers1;
    HashSet<int> numbers2;
    //分别进行numbers1和numbers2的值初始化或赋值
    numbers1.SymmetricExceptWith(numbers2);//求两个集合的对称差集。

    2.HashSet常用扩展方法

    2.1.Add,将项目添加到HashSet之中。

    2.2.Clear,清空HashSet里面的值。

    2.3.Remove,从HashSet中移除值。

    2.4Contains,判断HashSet是否包含指定项目。

    2.4Equals(Object),判断是否相等。

    3.HashSet与Linq操作

    HashSet<T>与LINQ的对等的方法

    UnionWith       ==>  Union

    IntersectWith  ==>  Interset

    ExceptWith     ==>  Except

    不提供排序     ==>  Distinct

    那么我们已经有很多的集合类型如List<T> ,Dictionary<TKey,TValue>或Hashtable等这些集合类型,我们该如何选定我应该采用的哪一个集合类型呢?

    “如果你必须建立新的设定,或则如果应用程序只需要存取提供的任务,那么使用任何的IEnumerable<T>集合都已经足够了。但是,如果应用程序需要存取其他值,或则不建议不需要建立新的集合,这时可使用HashSet<T>.”——摘自MSDN

    相关文章:

    C# 集合交、并、差、去重,对象集合交并差(需要引用linq)

    https://www.cnblogs.com/hao-1234-1234/p/10408602.html

  • 相关阅读:
    重载操作符- 友元函数- 非/模板类重载
    静态成员变量
    函数指针的使用
    高斯消元_HihoCoderOffer6_03
    多重背包(MultPack = ZeroOnePack + CompletePack)
    高斯消元
    textbox文本键盘全选
    BASE64-客户端(js)加码-服务器端(c#)解码,URL传递“汉字参数”解决方法
    Jquery获取input=text 的值
    sql server 2008 不允许保存更改,您所做的更改要求删除并重新创建以下表 的解决办法
  • 原文地址:https://www.cnblogs.com/hao-1234-1234/p/6354357.html
Copyright © 2011-2022 走看看