zoukankan      html  css  js  c++  java
  • 了解C#中的HashSet与示例

    在C#中引入HashSet

    在.NET框架中,有几个类可用于执行这些操作。一些课程如下:

    • 列表
    • 字典
    • 哈希集
    • 队列

    集合

    在C#编程中,像ArrayList,List这样的集合,只需添加其中的值,而不检查任何重复。为了避免这种重复的数据存储,.NET提供集合名称集。这是一个具有不同项目的集合类型。

    有两种类型的集合,SortedSetHastSet。SortedSet按照排序顺序存储数据,也可以消除重复。

    哈希集 vs SortedSet

    这两个类都存储非重复的项目。但是,如果要执行性能,并且不关心项目是否未分类存储,则进入HashSet但是,如果您希望项目在插入后进行排序,但可以进行性能打击,请选择“排序”

    本文分为六个部分,分别如下:

    第1节:HastSet的特点 
    第2节:消除HashSet中的重复数据条目 
    第3节:使用UnionWith()方法修改HashSet方法 
    第4节:使用ExceptWith()方法 
    修改Hashset第5节:使用SymmetricExceptWith()方法修改Hashset 
    第6节:检查添加,删除等操作的性能,包含HashSet和List。

    让我们开始吧

    第1节:HastSet的特点

    这是HashSet的一些突出特点

    • 这个类代表一组值。
    • 这个类提供了高性能的操作。
    • 这是一组不包含重复元素的集合,并且其中存储的元素没有特定的顺序。
    • 在.NET Framework 4.6版本中,HashSet 实现IReadOnlyCollection 界面连同ISet 接口。
    • 哈希集类对其中存储的元素数量没有任何最大容量。随着元素数量的增加,这种容量不断增加。

    第2节:消除C#HashSet中的重复

    步骤1:打开Visual Studio并创建名称为CS_Using_HashSet的控制台应用程序。

    步骤2:在Program.cs的Main()方法中,添加以下代码

    using System;
    using System.Collections.Generic;
     
    namespace CS_Using_HashSet
    {
        class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine("Using HashSet");
                //1. Defining String Array (Note that the string "mahesh" is repeated)
                string[] names = new string[] {
                    "mahesh",
                    "vikram",
                    "mahesh",
                    "mayur",
                    "suprotim",
                    "saket",
                    "manish"
                };
                //2. Length of Array and Printing array
                Console.WriteLine("Length of Array " + names.Length);
                Console.WriteLine();
                Console.WriteLine("The Data in Array");
                foreach (var n in names)
                {
                    Console.WriteLine(n);
                }
     
                Console.WriteLine();
                //3. Defining HashSet by passing an Array of string to it
                HashSet< string > hSet = new HashSet< string >(names);
                //4. Count of Elements in HashSet
                Console.WriteLine("Count of Data in HashSet " + hSet.Count);
                Console.WriteLine();
                //5. Printing Data in HashSet, this will eliminate duplication of "mahesh"
                Console.WriteLine("Data in HashSet");
                foreach (var n in hSet)
                {
                    Console.WriteLine(n);
                }    
                Console.ReadLine();
            }
        }
    }

    上述代码具有以下规格(注:代码中的注释号与以下编号相符)

    1.声明一个名称名称的字符串数组它在其中存储名称。该数组具有字符串“mahesh”的重复条目。

    2.打印其中的数组长度和数据。

    3.定义一个类型为字符串的HashSet 该对象使用数组进行初始化,该数组自动从数组中添加HashSet中的项。

    4.如第1节所述,HashSet对象不允许重复输入,因此结果将显示HashSet中存在的数据的计数小于数组计数。

    5.在HashSet中显示数据。

    运行应用程序,并显示以下结果:

    哈希集 - 重复消除

    第3节:使用UnionWith()方法修改HashSet

    UnionWith()方法用于修改HashSet,以包含其中存在的所有元素以及与其建立联合的其他(IEnumerable)集合中的元素。

    以下代码是UnionWith()上的实现。

    步骤1:在项目的Main()方法中添加以下代码。

    string[] names1 = new string[] {
        "mahesh","sabnis","manish","sharma","saket","karnik"
    };
     
    string[] Names2 = new string[] {
        "suprotim","agarwal","vikram","pendse","mahesh","mitkari"
    };
    //2.
     
    HashSet< string > hSetN1 = new HashSet< string >(Names1);
    Console.WriteLine("Data in First HashSet");
    foreach (var n in hSetN1)
    {
        Console.WriteLine(n);
    }
    Console.WriteLine("_______________________________________________________________");
    HashSet< string > hSetN2 = new HashSet< string >(names2);
    Console.WriteLine("Data in Second HashSet");
    foreach (var n in hSetN2)
    {
        Console.WriteLine(n);
    }
    Console.WriteLine("________________________________________________________________");
    //3.
    Console.WriteLine("Data After Union");
    hSetN1.UnionWith(hSetN2);
    foreach (var n in hSetN1)
    {
        Console.WriteLine(n);
    }

    以上代码具有以下规格(注:以下编号与注释相符)。

    数组对象声明Name1和Names2,其中包含字符串数据。

    2.本步骤定义了两个HashSet的对象hSetN1hSetN2基于names1names2分别和来自两个HashSet的数据被打印。

    此步骤在hSetN1上调用UnionWith()方法,并将hSetN2 对象传递给它,并在union之后显示hSetN1中的所有数据。

    运行应用程序,将显示以下结果:

    hashset-unionwith

    第4节:使用ExceptWith()方法修改哈希集

    该方法用于通过删除与其他集合中的元素匹配的所有元素来修改HashSet。

    步骤1:在Main()方法中添加以下代码。代码使用第3节中声明的hSetN2,并使用names1数组声明一个新的HashSet,该数组用于声明hSetN1。

    Console.WriteLine();
    Console.WriteLine("_________________________________");
    Console.WriteLine("Data in HashSet before using Except With");
    Console.WriteLine("_________________________________");
    //storing data of hSetN3 in temporary HashSet
    HashSet< string > hSetN3 = new HashSet< string >(names1);
    foreach (var n in hSetN3)
    {
        Console.WriteLine(n);
    }
    Console.WriteLine();
    Console.WriteLine("_________________________________");
    Console.WriteLine("Using Except With");
    Console.WriteLine("_________________________________");
    hSetN3.ExceptWith(hSetN2);
    foreach (var n in hSetN3)
    {
        Console.WriteLine(n);
    }

    运行应用程序后,将显示以下结果:

    除了结果

    上述结果表明,当通过将hSetN2参数传递给hSetN2 HashSet的ExceptWith()方法时,从hSetN3中删除匹配的字符串“mahesh”,并显示剩余的字符串。

    第5节:使用 SymmetricExceptWith()方法修改Hashset

    此方法修改HashSet对象以包含仅存在于两个集合之一中的那些元素,但不能同时包含两个。

    所有匹配的元素将被删除。

    步骤1:在Main()方法中添加以下代码。代码useshSetN2在第3节中声明,并使用数组names1声明一个新的HashSet hSet4。

    HashSet< string > hSetN4 = new HashSet< string >(names1);
    Console.WriteLine("_________________________________");
    Console.WriteLine("Elements in HashSet before using SymmetricExceptWith");
    Console.WriteLine("_________________________________");
    Console.WriteLine("HashSet 1");
    foreach (var n in hSetN4)
    {
        Console.WriteLine(n);
    }
    Console.WriteLine("HashSet 2");
    foreach (var n in hSetN2)
    {
        Console.WriteLine(n);
    }
    Console.WriteLine("_________________________________");
    Console.WriteLine("Using SymmetricExceptWith");
    Console.WriteLine("_________________________________");
    hSetN4.SymmetricExceptWith(hSetN2);
    foreach (var n in hSetN4)
    {
        Console.WriteLine(n);
    }

    通过将hSetN2 HashSet传递给它,在HSetN4 HashSet上调用SymmetircExceptWith()方法。这两个HashSets都包含一个字符串名称“mahesh”。

    通过消除匹配的条目,hSetN4将与hSetN2的值合并。运行应用程序后,结果如下:

    对称除结果

    第6节:检查HashSet vs List上的添加,删除,包含操作的性能。

    以上所有部分都介绍了HashSet的各种方法。

    但是,当开发人员想要根据性能选择最合适的集合类型作出决定时,重要的是要检查哪些操作经常在集合上执行。

    通常,添加,删除,包含是对内存中集合执行的操作。要执行List和HashSet之间的添加,删除和包含操作的比较,使用以下字符串数组。(注:您可以使用任何其他数据)

    static string[] names = new string[] {
        "Tejas", "Mahesh", "Ramesh", "Ram", "GundaRam", "Sabnis", "Leena",
        "Neema", "Sita" , "Tejas", "Mahesh", "Ramesh", "Ram",
        "GundaRam", "Sabnis", "Leena", "Neema", "Sita" ,
        "Tejas", "Mahesh", "Ramesh", "Ram", "GundaRam",
        "Sabnis", "Leena", "Neema", "Sita" , "Tejas",
        "Mahesh", "Ramesh", "Ram", "GundaRam", "Sabnis",
        "Leena", "Neema", "Sita",
        "Tejas", "Mahesh", "Ramesh", "Ram", "GundaRam", "Sabnis", ……            };

    (字符串总数为:550)

    将以下方法添加到Program.cs

    static void Get_Add_Performance_HashSet_vs_List()
    {
         
        Console.WriteLine("____________________________________");
        Console.WriteLine("List Performance while Adding Item");
        Console.WriteLine();
        List< string > lstNames = new List< string >();
        var s2 = Stopwatch.StartNew();
        foreach (string s in names)
        {
            lstNames.Add(s);
        }
        s2.Stop();
     
        Console.WriteLine(s2.Elapsed.TotalMilliseconds.ToString("0.000 ms"));            Console.WriteLine();
        Console.WriteLine("Ends Here");
        Console.WriteLine();
        Console.WriteLine("____________________________________");
        Console.WriteLine("HashSet Performance while Adding Item");
        Console.WriteLine();
        
        HashSet< string > hStringNames = new HashSet< string >(StringComparer.Ordinal);
        var s1 = Stopwatch.StartNew();
        foreach (string s in names)
        {
            hStringNames.Add(s);
        }
        s1.Stop();
     
        Console.WriteLine(s1.Elapsed.TotalMilliseconds.ToString("0.000 ms"));            Console.WriteLine();
        Console.WriteLine("Ends Here");
        Console.WriteLine("____________________________________");
        Console.WriteLine();
        
    }

    HashSet vs List - Add()方法

    上述方法通过从名称数组中迭代字符串对List和HashSet执行Add()操作

    操作的性能是通过计算秒表从类System.Diagnostics程序命名空间。

    运行应用程序,并显示以下结果:

    请注意,下面的结果显示了时间差我的机器,它可以执行样本时,您的计算机上有所不同。

    加成项目

    与HashSet相比,List <>花费更少的时间来添加字符串。

    原因之一是List.Add()只是将一个项目添加到列表,而HashSet.Add()将跳过新项目(如果它等于其中一个现有项目)。与List.Add()方法相比,这需要时间来执行HashSet.Add()方法。

    HashSet vs List - Contains()方法

    在Program.cs中添加以下方法

    static void Get_Contains_Performance_HashSet_vs_List()
    {
      
        Console.WriteLine("____________________________________");
        Console.WriteLine("List Performance while checking Contains operation");
        Console.WriteLine();
        List< string > lstNames = new List< string >();
        var s2 = Stopwatch.StartNew();
        foreach (string s in names)
        {
            lstNames.Contains(s);
        }
        s2.Stop();
     
        Console.WriteLine(s2.Elapsed.TotalMilliseconds.ToString("0.000 ms"));            Console.WriteLine();
        Console.WriteLine("Ends Here");
        Console.WriteLine();
        Console.WriteLine("____________________________________");
        Console.WriteLine("HashSet Performance while checking Contains operation");
        Console.WriteLine();
     
        HashSet< string > hStringNames = new HashSet< string >(StringComparer.Ordinal);
        var s1 = Stopwatch.StartNew();
        foreach (string s in names)
        {
            hStringNames.Contains(s);
        }
        s1.Stop();
     
        Console.WriteLine(s1.Elapsed.TotalMilliseconds.ToString("0.000 ms"));
        Console.WriteLine();
        Console.WriteLine("Ends Here");
        Console.WriteLine("____________________________________");
        Console.WriteLine();
     
    }

    上述方法检查List和HashSet是否包含作为输入参数传递给Contains()方法的项。运行应用程序,结果将显示如下图所示

    包含操作

    结果清楚地表明,HashSet提供了比List更快的查找元素。

    这是因为HashSet中没有重复的数据。HashSet为其中的每个项目维护哈希,并将它们排列在单独的桶中,​​其中包含存储在HashSet中的项目的每个字符的散列。

    当查找发生时,HashSet会将其从第一个字符开始进行散列并将其跳转到匹配的每个字符,并从HashSet中提取元素。

    HashSet vs List - Remove()方法

    在Program.cs中添加以下方法

    static void Get_Remove_Performance_HashSet_vs_List()
    {
       
        Console.WriteLine("____________________________________");
        Console.WriteLine("List Performance while performing Remove item operation");
        Console.WriteLine();
        List< string > lstNames = new List< string >();
        var s2 = Stopwatch.StartNew();
        foreach (string s in names)
        {
            lstNames.Remove(s);
        }
        s2.Stop();
     
        Console.WriteLine(s2.Elapsed.TotalMilliseconds.ToString("0.000 ms"));            Console.WriteLine();
        Console.WriteLine("Ends Here");
        Console.WriteLine();
        Console.WriteLine("____________________________________");
        Console.WriteLine("HashSet Performance while performing Remove item operation");
        Console.WriteLine();
     
        HashSet< string > hStringNames = new HashSet< string >(StringComparer.Ordinal);
        var s1 = Stopwatch.StartNew();
        foreach (string s in names)
        {
            hStringNames.Remove(s);
        }
        s1.Stop();
     
        Console.WriteLine(s1.Elapsed.TotalMilliseconds.ToString("0.000 ms"));            Console.WriteLine();
        Console.WriteLine("Ends Here");
        Console.WriteLine("____________________________________");
        Console.WriteLine();
     
    }

    上述方法使用Remove()方法执行List和HashSet上的删除操作。运行应用程序,结果将显示如下图所示:

    执行删除操作

    上图清楚地显示了HashSet的删除操作比List更快。“删除”操作也与“包含”操作类似。

  • 相关阅读:
    数据结构与算法(15)——冒泡法和选择法排序
    数据结构与算法(14)——二分查找算法
    数据结构与算法(13)—顺序查找法
    数据结构与算法(12)——动态规划案例
    Object Detection的一些进展(Valse2020.4.30)
    机器学习(1)——模型评估与选择
    数据结构与算法(12)—分治策略
    数据结构与算法(11)—递归
    数据结构与算法(10)——有序表OrderedList
    数据结构与算法(9)——无序表List
  • 原文地址:https://www.cnblogs.com/Javi/p/6794660.html
Copyright © 2011-2022 走看看