乐趣区

关于c#:如何使用-C-中的-HashSet

译文链接:https://www.infoworld.com/art…

HashSet 是一个优化过的无序汇合,提供对元素的高速查找和高性能的 set 汇合 操作,而且 HashSet 是在 .NET 3.5 中被引入的,在 System.Collection.Generic 命名空间下,这篇就来讨论一下如何应用这个 HashSet。

要运行本篇文章的案例代码,你须要装置一下 Visual Studio 2019,如果没有的话能够到官网下载一下。

应用 VS 创立一个 .NET Core 控制台程序

首先,我通过 VS2019 创立一个 .NET Core 控制台程序,创立能够参考上面步骤:

  • 关上 Visual Studio IDE
  • 点击创立 Create new project
  • Create new project 窗口上,从模板列表中抉择:Console App (.NET Core)
  • 点击下一步
  • Configure your new project 界面填好你的项目名称和寄存门路

这样咱们就创立好了一个新我的项目,本文的前面局部就会在这个我的项目里来给大家分享 HashSet 的一些必备常识。

HashSet 到底是什么

所谓的 HashSet,指的就是 System.Collections.Generic 命名空间下的 HashSet<T> 类,它是一个高性能,无序的汇合,因而 HashSet 它并不能做排序操作,也不能蕴含任何反复的元素,Hashset 也不能像数组那样应用索引,所以在 HashSet 上你无奈应用 for 循环,只能应用 foreach 进行迭代,HashSet 通常用在解决元素的唯一性上有着超高的性能。

HashSet<T> 实现了如下几个接口:


public class HashSet<T> : System.Collections.Generic.ICollection<T>,
System.Collections.Generic.IEnumerable<T>, 
System.Collections.Generic.IReadOnlyCollection<T>,
System.Collections.Generic.ISet<T>,
System.Runtime.Serialization.IDeserializationCallback,
System.Runtime.Serialization.ISerializable
{
}

HashSet 只能蕴含惟一的元素,它的内部结构也为此做了专门的优化,值得注意的是,HashSet 也能够寄存单个的 null 值,能够得出这么一个论断:如何你想领有一个具备惟一值的汇合,那么 HashSet 就是你最好的抉择,何况它还具备超高的检索性能。

从 HashSet 中查找一个元素

如果想判断某一个元素是否在 HashSet 内,倡议应用 Contains 进行判断,代码如下:


        static void Main(string[] args)
        {HashSet<string> hashSet = new HashSet<string>();
            hashSet.Add("A");
            hashSet.Add("B");
            hashSet.Add("C");
            hashSet.Add("D");
            if (hashSet.Contains("D"))
                Console.WriteLine("The required element is available.");
            else
                Console.WriteLine("The required element isn’t available.");
            Console.ReadKey();}

HashSet 中的元素唯一性

如果你向 HashSet 中插入反复的元素,它的外部会漠视这次操作而不像别的汇合一样抛出异样,接下来展现一下代码:


        static void Main(string[] args)
        {HashSet<string> hashSet = new HashSet<string>();
            hashSet.Add("A");
            hashSet.Add("B");
            hashSet.Add("C");
            hashSet.Add("D");
            hashSet.Add("D");
            Console.WriteLine("The number of elements is: {0}", hashSet.Count);
            Console.ReadKey();}

当你执行了这个程序,输入后果如下图:

当初能够考虑一下上面的代码段,它展现了反复的元素是如何被剔除的。


        static void Main(string[] args)
        {string[] cities = new string[] {
                "Delhi",
                "Kolkata",
                "New York",
                "London",
                "Tokyo",
                "Washington",
                "Tokyo"
            };
            HashSet<string> hashSet = new HashSet<string>(cities);
            foreach (var city in hashSet)
            {Console.WriteLine(city);
            }
        }

当你执行完下面的程序,反复的城市名称曾经被移除了。

从 HashSet 中移除元素

从 HashSet 中删除某一个元素能够调用 Remove 办法,它的语法结构如下:


public bool Remove (T item);

如果在汇合中找到了这个元素,Remove 办法将会删除这个元素并且返回 true,否则返回 false。

上面的代码片段展现了如何应用 Remove 办法删除 HashSet 中的元素


string item = "D";
if(hashSet.Contains(item))
{hashSet.Remove(item);
}

如果你想删除 HashSet 中的所有元素,能够调用 Clear 办法。

HashSet 的 set 操作

HashSet 提供了十分多的办法用于 set 汇合 操作上,比如说:IntersectWith, UnionWith, IsProperSubsetOf, ExceptWith, 和 SymmetricExceptWith

IsProperSubsetOf

这个 IsProperSubsetOf 用于判断 HashSet 是否为某一个汇合的齐全子集,能够看上面的例子:


HashSet<string> setA = new HashSet<string>() { "A", "B", "C", "D"};
HashSet<string> setB = new HashSet<string>() { "A", "B", "C", "X"};
HashSet<string> setC = new HashSet<string>() { "A", "B", "C", "D", "E"};
if (setA.IsProperSubsetOf(setC))
   Console.WriteLine("setC contains all elements of setA.");
if (!setA.IsProperSubsetOf(setB))
   Console.WriteLine("setB does not contains all elements of setA.");

如果你执行了下面这个程序,你会在管制台上看到如下的输入:

UnionWith

UnionWith 办法罕用于汇合的合并,比如说上面的代码:


HashSet<string> setA = new HashSet<string>() { "A", "B", "C", "D", "E"};
HashSet<string> setB = new HashSet<string>() { "A", "B", "C", "X", "Y"};
setA.UnionWith(setB);
foreach(string str in setA)
{Console.WriteLine(str);
}

当你执行完下面的代码,SetB 汇合会被 SetA 汇合吞掉,最初 SetA 汇合将会是包含:"A", "B", "C", "D", "E", "X", and "Y"

IntersectWith

IntersectWith 办法罕用于示意两个 HashSet 的交加,上面的例子或者会让你更加了解:


HashSet<string> setA = new HashSet<string>() { "A", "B", "C", "D", "E"};
HashSet<string> setB = new HashSet<string>() { "A", "X", "C", "Y"};
setA.IntersectWith(setB);
foreach (string str in setA)
{Console.WriteLine(str);
}

当你运行了下面的这段程序,只有两个 HashSet 中都存在的元素才会输入到控制台中,输入后果如下所示:

ExceptWith

ExceptWith 办法示意数学上的减法操作,这个工夫复杂度是 O(N),假设你有两个 HashSet 汇合,别离叫 setA 和 setB,并且用了上面的语句。


setA.ExceptWith(setB);

它返回的元素为:setA 中有,setB 中没有 的最终后果,如果还不明确的话, 应用如下代码辅助了解:


HashSet<string> setA = new HashSet<string>() { "A", "B", "C", "D", "E"};
HashSet<string> setB = new HashSet<string>() { "A", "X", "C", "Y"};
setA.ExceptWith(setB);
foreach (string str in setA)
{Console.WriteLine(str);
}

当你执行了下面这段程序,元素 B,D,E 将会输入到管制台上。

SymmetricExceptWith

SymmetricExceptWith 办法罕用于批改一个 HashSet 来寄存两个 HashSet 都是惟一的元素,换句话说,我要的就是两个汇合都不全有的元素,如果还不明确的话,思考上面的代码段:


HashSet<string> setA = new HashSet<string>() { "A", "B", "C", "D", "E"};
HashSet<string> setB = new HashSet<string>() { "A", "X", "C", "Y"};
setA.SymmetricExceptWith(setB);
foreach (string str in setA)
{Console.WriteLine(str);
}

当你执行完下面的代码,你会发现,setA 中有而 setB 中没有 和 setB 中有而 setA 中没有的元素将会输入到控制台中。

咱们晓得数组的均匀复杂度是 O(N),这里的 n 示意数组里的元素数量,而拜访 HashSet 中的某一个元素,它的复杂度为 O(1),这个常量复杂度就决定了 HashSet 在疾速检索 和执行 set 汇合 操作上是一个十分好的抉择,你也能够应用 List 去存储某些有指定程序的元素,同时也能够蕴含反复的值。

更多高质量干货:参见我的 GitHub: dotnetfly

退出移动版