کار با HashSet در#C
پنجشنبه 14 مرداد 1395در این مقاله HashSet بهعنوان یک کالکشن -المان- تکراری ناپذیر معرفی شده و برخی از متدهای مهم آن همراه با مثال معرفی میگردند.
HashSet یک کالکشن (collection) نامرتب از المانهای منحصربهفرد و غیرتکراری است که در .NET 3.5 معرفی شد و داخل namespace System.Collection.Generic قرار دارد و کاربرد آن زمانیست که بخواهید از تکراریشدن نمونههای واردشده به کالکشن جلوگیری کنید. در مواردی که کارایی مدنظر باشد، این کالکشن از لیست (List) مناسبتر است. در این مقاله کار را با ساختن یک HashSet ساده شروع میکنیم که در ادامه کارهای مختلفی روی HashSet انجام میگیرد. در پایانِ این مقاله به شما نشان خواهم داد که چگونه یک HashSet را از نوعهای مختلفی بسازیم و از تکراریشدن ورودیهای آن جلوگیری بهعمل آوریم.اجازه بدید کار را با یه مثال شروع کنیم:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace HashSetDemo { class Program { static void Main(string[] args) { HashSet < string > names = new HashSet < string > { "Rajeev", "Akash", "Amit" }; foreach(var name in names) { Console.WriteLine(name); } Console.ReadKey(); } } }
در کد بالا، ما یک HashSet ساده را از نوع رشتهای (string) پدید آورده و رشتهها را بهآن اضافه میکنیم. درعین حال میتوانیم رشتهها را توسط متد add اضافه کنیم. در قطعهای که پایین آمده، نحوه استفاده از متد add را ملاحظه میکنیم. ما الان سعی میکنیم رشتههای تکراریای را اضافه کنیم و ببینیم چه اتفاقی میافتد.
using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace HashSetDemo { class Program { static void Main(string[] args) { HashSet < string > names = new HashSet < string > { "Rajeev", "Akash", "Amit" }; names.Add("Rajeev"); //duplicates are not added into collection. foreach(var name in names) { Console.WriteLine(name); } Console.ReadKey(); } } }
در قطعهکد آمده در بالا با اینکه ما سعی کردیم رشتههای تکراری را وارد کنیم، اما با هیچ خطایی مواجه نشدیم ولی وقتی کالکشن را تکرار کنیم، دیگه نمیتوانیم رشته را پیدا کنیم. این نشاندهندهی این است که ما نمیتوانیم المانهای تکراری را به HashSet اضافه کنیم. الان دیگه وقت آن رسیده که به بعضی از متدهای مهم HashSet نگاهی بیاندازیم.
UnionWith
این متد المانهایی را که در هردو کالکش قرار دارند، در کالکشن مورد فراخوانی ترکیب میکند.
using System;
using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace HashSetDemo { class Program { static void Main(string[] args) { HashSet < string > names = new HashSet < string > { "Rajeev", "Akash", "Amit" }; HashSet < string > names1 = new HashSet < string > { "Rajeev", "Akash", "Amit", "Deepak", "Mohit" }; names.UnionWith(names1); foreach(var name in names) { Console.WriteLine(name); } Console.ReadKey(); } } }
IntersectWith
این متد المانهایی را که بین دو کالکشن مشترک هستند باهم ترکیب میکند.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace HashSetDemo { class Program { static void Main(string[] args) { HashSet < string > names = new HashSet < string > { "Rajeev", "Akash", "Amit" }; HashSet < string > names1 = new HashSet < string > { "Rajeev", "Akash", "Amit", "Deepak", "Mohit" }; names.IntersectWith(names1); foreach(var name in names) { Console.WriteLine(name); } Console.ReadKey(); } } }
ExceptWith
این متد تمامی المانهای کالکشن دیگر را از کالکشن موردفراخوانی حذف میکند.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace HashSetDemo { class Program { static void Main(string[] args) { HashSet < string > names = new HashSet < string > { "Rajeev", "Akash", "Amit" }; HashSet < string > names1 = new HashSet < string > { "Rajeev", "Akash", "Amit", "Deepak", "Mohit" }; names1.ExceptWith(names); foreach(var name in names1) { Console.WriteLine(name); } Console.ReadKey(); } } }
اکنون اجازه دهید یک مرحله جلوتر برویم، کلاسی را ساخته و سعی کنیم یک HashSet از نوع کلاس ایجاد کرده و تلاش نماییم المانهایی تکراری را بهآن اضافه کنیم.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace HashSetDemo { class Program { static void Main(string[] args) { Console.WriteLine("-----Custom HashSet With Duplicates----"); HashSet < Employee > employees = new HashSet < Employee > { { new Employee { Emp_Id = 1, Emp_name = "Rajeev", Dept_name = "IT" } }, { new Employee { Emp_Id = 1, Emp_name = "Rajeev", Dept_name = "IT" } }, { new Employee { Emp_Id = 3, Emp_name = "Akash", Dept_name = "IT" } }, { new Employee { Emp_Id = 4, Emp_name = "Amit", Dept_name = "IT" } } }; Console.WriteLine("{0,-6}{1,10}{2,-8}", "Emp_Id", "Emp_name", "Dept_name"); Console.WriteLine("=============================="); foreach(var employee in employees) { Console.WriteLine("{0,-8}{1,-10}{2,5}", employee.Emp_Id, employee.Emp_name, employee.Dept_name); } Console.WriteLine("=============================="); Console.ReadKey(); } } public class Employee { public int Emp_Id { get; set; } public string Emp_name { get; set; } public string Dept_name { get; set; } } }
ما درمییابیم که HashSet در کالکشن اجازهی تکرار را نمیدهد لیکن همچنان در خروجی رکوردهای تکراری داریم. بهمنظور غلبه بر این مشکل نیازمند پیادهسازی رابط (interface) IEquatable، حذف موارد مساوی، ومتد GetHashCode میباشیم.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace HashSetDemo { class Program { static void Main(string[] args) { Console.WriteLine("-----Custom HashSet With Duplicates----"); HashSet < Employee > employees = new HashSet < Employee > { { new Employee { Emp_Id = 1, Emp_name = "Rajeev", Dept_name = "IT" } }, { new Employee { Emp_Id = 1, Emp_name = "Rajeev", Dept_name = "IT" } }, { new Employee { Emp_Id = 3, Emp_name = "Akash", Dept_name = "IT" } }, { new Employee { Emp_Id = 4, Emp_name = "Amit", Dept_name = "IT" } } }; Console.WriteLine("{0,-6}{1,10}{2,-8}", "Emp_Id", "Emp_name", "Dept_name"); Console.WriteLine("=============================="); foreach(var employee in employees) { Console.WriteLine("{0,-8}{1,-10}{2,5}", employee.Emp_Id, employee.Emp_name, employee.Dept_name); } Console.WriteLine("=============================="); Console.ReadKey(); } } public class Employee: IEquatable < Employee > { public int Emp_Id { get; set; } public string Emp_name { get; set; } public string Dept_name { get; set; } public bool Equals(Employee other) { return this.Emp_Id.Equals(other.Emp_Id); } public override int GetHashCode() { return this.Emp_Id.GetHashCode(); } } }
بنابراین HashSet یک کالکشن عمومیست (generic) که اجازهی تکرار را نمیدهد. ما میتوانیم برای حذف تکراریهای هر کالکشنی مانند List از HashSet استفاده کنیم.
using System; using System.Collections.Generic; namespace HashSetDemo { public class Program { public static void Main() { HashSet<string> names=new HashSet<string>{"Rajeev", "Akash", "Amit"}; foreach(var country in names) { Console.WriteLine(country); } names.Add("Rajeev"); Console.WriteLine("---------"); //duplicates are not added into collection. foreach(var name in names) { Console.WriteLine(name); } //ExceptWith HashSet<string> names1=new HashSet<string>{"Rajeev", "Akash", "Amit","Deepak","Mohit"}; names1.ExceptWith(names); Console.WriteLine("-----ExceptWith(elements not present in second(names)----"); foreach(var name in names1) { Console.WriteLine(name); } //IntersectWith names.IntersectWith(names1); Console.WriteLine("-----IntersectWith(elements common----"); foreach(var name in names1) { Console.WriteLine(name); } //UnionWith names.UnionWith(names1); Console.WriteLine("-----UnionWith----"); foreach(var name in names) { Console.WriteLine(name); } Console.WriteLine("-----Custom HashSet With Duplicates----"); HashSet<Employee> employees=new HashSet<Employee> { {new Employee{Emp_Id=1,Emp_name="Rajeev",Dept_name="IT"}}, {new Employee{Emp_Id=1,Emp_name="Rajeev",Dept_name="IT"}}, {new Employee{Emp_Id=3,Emp_name="Akash",Dept_name="IT"}}, {new Employee{Emp_Id=4,Emp_name="Amit",Dept_name="IT"}} }; Console.WriteLine("{0,-6}{1,10}{2,-8}","Emp_Id","Emp_name","Dept_name"); Console.WriteLine("=============================="); foreach(var employee in employees) { Console.WriteLine("{0,-8}{1,-10}{2,5}",employee.Emp_Id,employee.Emp_name,employee.Dept_name); } Console.WriteLine("=============================="); } } //Implement IEquatable Interface methods Equals and GetHashCode public class Employee:IEquatable<Employee> { public int Emp_Id{get;set;} public string Emp_name{get;set;} public string Dept_name{get;set;} public bool Equals(Employee other) { return this.Emp_Id.Equals(other.Emp_Id); } public override int GetHashCode() { return this.Emp_Id.GetHashCode(); } } }
- C#.net
- 2k بازدید
- 5 تشکر