在C#中引入HashSet

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

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

集合

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

有两种类型的集合,SortedSet和HastSet。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的对象hSetN1和hSetN2基于names1和names2分别和来自两个HashSet的数据被打印。

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

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

第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更快。“删除”操作也与“包含”操作类似。

了解C#中的HashSet与示例的更多相关文章

  1. Hash Map 在java中的解释及示例

    目录 HashMap在java中的应用及示例 HashMap的内部结构 HashMap的性能 同步HashMap HashMap的构造函数 HashMap的时间复杂度 HashMap的方法 1. vo ...

  2. jQuery中$.fn的用法示例介绍

    $.fn是指jquery的命名空间,加上fn上的方法及属性,会对jquery实例每一个有效,下面有个不错的示例,喜欢的朋友可以参考下 如扩展$.fn.abc(),即$.fn.abc()是对jquery ...

  3. demo工程的清单文件及activity中api代码简单示例

    第一步注册一个账户,并创建一个应用.获取app ID与 app Key. 第二步下载sdk 第三步新建工程,修改清单文件,导入相关的sdk文件及调用相应的api搞定. 3.1 修改清单文件,主要是加入 ...

  4. [转]Linux中find常见用法示例

    Linux中find常见用法示例[转]·find   path   -option   [   -print ]   [ -exec   -ok   command ]   {} \;find命令的参 ...

  5. wpf将表中数据显示到datagrid示例(转)

    原文:http://www.jb51.net/article/47120.htm 这篇文章主要介绍了wpf将表中数据显示到datagrid示例,需要的朋友可以参考下 a.在.xaml文件中拖入一个da ...

  6. oracle中to_date详细用法示例(oracle日期格式转换)

    这篇文章主要介绍了oracle中to_date详细用法示例,包括期和字符转换函数用法.字符串和时间互转.求某天是星期几.两个日期间的天数.月份差等用法 TO_DATE格式(以时间:2007-11-02 ...

  7. vue不通过路由直接获取url中参数的方法示例

    vue不通过路由直接获取url中参数的方法示例 vuejs取得URL中参数的值地址:http://localhost:3333/#/index?id=128console.log(this.$rout ...

  8. Python的collections模块中namedtuple结构使用示例

      namedtuple顾名思义,就是名字+元组的数据结构,下面就来看一下Python的collections模块中namedtuple结构使用示例 namedtuple 就是命名的 tuple,比较 ...

  9. 【转载】D3D中的Texture应用示例

    原文:D3D中的texture应用示例 本文列举了Direct3D中各种纹理应用实现:黑暗贴图,发光贴图,漫反射映射贴图,细节纹理,纹理混合,有较详尽的注解.其中黑暗贴图,发光贴图,细节纹理都是采用多 ...

随机推荐

  1. ajax全局事件

    作用:当你的页面存在很多ajax事件的话,我们有一些信息是公共的,可以复用,我们可以用全局事件进行编写,因为每一个ajax事件调用,都会触发ajax全局事件. jquery的ajax方法的全部全局事件 ...

  2. jmeter(二十四)dubbo接口测试

    最近工作中接到一个需求,需要对一个MQ消息队列进行性能测试,测试其消费能力,开发提供了一个dubbo服务来供我调用发送消息. 这篇博客,介绍下如何利用jmeter来测试dubbo接口,并进行性能测试. ...

  3. 安装kubelet报错 : Depends: init-system-helpers (>= 1.18~) but 1.14ubuntu1 is to be installed

    解决办法: wget http://launchpadlibrarian.net/173841617/init-system-helpers_1.18_all.deb dpkg -i init-sys ...

  4. .net core实践系列之SSO-同域实现

    前言 SSO的系列还是以.Net Core作为实践例子与大家分享,SSO在Web方面复杂度分同域与跨域.本篇先分享同域的设计与实现,跨域将在下篇与大家分享. 如有需要调试demo的,可把SSO项目部署 ...

  5. 一起学习造轮子(三):从零开始写一个React-Redux

    本文是一起学习造轮子系列的第三篇,本篇我们将从零开始写一个React-Redux,本系列文章将会选取一些前端比较经典的轮子进行源码分析,并且从零开始逐步实现,本系列将会学习Promises/A+,Re ...

  6. python读取/创建XML文件

    Python中定义了很多处理XML的函数,如xml.dom,它会在处理文件之前,将根据xml文件构建的树状数据存在内存.还有xml.sax,它实现了SAX API,这个模块牺牲了便捷性,换取了速度和减 ...

  7. matplotlib 入门之Pyplot tutorial

    文章目录 pyplot 介绍 修饰你的图案 格式字符串 [color][marker][line] Colors Markers Line Styles 利用关键字作图(大概是数据映射到属性吧) 传入 ...

  8. Let's-Bug修复日志

    Version 1.1 2015/11/16 修复了上传图片画质问题的Bug 修复了搜索功能的部分Bug 增加了下拉刷新的功能 修复了部分界面跳转之间的问题    

  9. TCP粘包问题解析与解决

    一.粘包分析 作者本人在写一个FTP项目时,在文件的上传下载模块遇到了粘包问题.在网上找了一些解决办法,感觉对我情况都不好用,因此自己想了个比较好的解决办法,提供参考 1.1 粘包现象 在客户端与服务 ...

  10. ES使用C#添加和更新文档

    ElasticSearch 使用C#添加和更新文档 这是ElasticSearch 2.4 版本系列的第四篇: 第一篇:ES1:Windows下安装ElasticSearch 第二篇:ES2:Elas ...