Lập trình C# - Sử dụng IComparable và IComparer
Sử dụng IComparable và IComparer
Trong C#, khi bạn làm việc với một nhóm các đối tượng trong một mảng, một danh sách v.v. thì có một yêu cầu thường gặp là sắp xếp danh sách đó. Bạn có thể dễ dàng sắp xếp các phần tử với các kiểu cơ bản như int, float, string v.v. nhờ sử dụng phương thức Sort() có sẵn trong hầu hết các lớp liên quan đến Collection. Nhưng đối với những kiểu dữ liệu do người dùng tự định nghĩa thì bạn cần phải chỉ định rõ cách các đối tượng này được so sánh với nhau như thế nào, đơn giản là bởi vì muốn sắp xếp được thì trước tiên ta phải so sánh được.
Để cho các bạn dễ hiểu thì chúng ta sẽ xét một ví dụ sau: Tạo một danh sách các số nguyên và sắp xếp danh sách đó theo thứ tự tăng dần. Yêu cầu sử dụng List<> để chứa các số nguyên đó và sử dụng phương thức Sort() có sẵn trong List<>. Đoạn code theo yêu cầu này có thể là như sau:
Sắp xếp với IComparable
- Ở đây ta sẽ sắp xếp thông qua phương thức Sort của danh sách các đối tượng được lưu trữ bằng List<T>, nếu T là danh sách các kiểu dữ liệu cơ bản như int, float, string của C# thì bạn có thể sắp xếp được với Sort() nhưng với 1 kiểu dữ liệu do người dùng tự định nghĩa thì bạn phải chỉ rõ tiêu chí mà bạn muốn sắp xếp, và khi sử dụng hàm Sort này đối với List dữ liệu đó thì hàm Sort sẽ thực thi sắp xếp danh sách dựa trên tiêu trí này.
- Giá trị trả về nhỏ hơn 0 nghĩa là đối tượng hiện tại sẽ nhỏ hơn (hay đứng trước) đối tượng other. Giá trị trả về là 0 thì hai đối tượng bằng nhau, còn nếu giá trị trả về lớn hơn 0 thì đối tượng hiện tại lớn hơn (hay đứng sau) đối tượng other.
- Để khai báo tiêu chí sắp xếp vời hàm Sort chúng ta sẽ cần phải Implement Interface IComparable trên class được định nghĩa để chỉ ra thuộc tính mà ta sử dụng cho việc sắp xếp thông qua phương thức CompareTo của interface này.
Bước 1: Kích chuột phải vào Solution chọn Add -> New Project ->Nhập tên (IComparablePerson)-> Chọn OK
Bước 2: Tạo interface có tên Person chứa các phương thức
using System;
using System.Collections.Generic;
using System.Text;
namespace IComparablePerson
{
public class Person : IComparable<Person>
{
public int Age { get; set; }
public string Name { get; set; }
public int CompareTo(Person other)
{
return this.Age.CompareTo(other.Age);
}
}
}
Bước 2: Trong Program code test như sau:
using System;
using System.Collections.Generic;
namespace IComparablePerson
{
class Program
{
static void Main(string[] args)
{
List<Person> personList = new List<Person>();
personList.Add(new Person { Age = 10, Name = "John" });
personList.Add(new Person { Age = 15, Name = "Ann" });
personList.Add(new Person { Age = 8, Name = "Kevin" });
personList.Sort();
foreach (var item in personList)
{
Console.WriteLine(item.Name + ":" + item.Age);
}
Console.ReadKey(true);
}
}
}
Bước 3: Nhấn Ctrl+F5 để chạy và xem kết quả
Kevin:8
John:10
Ann:15
Sắp xếp với IComparer
- Tương tự như với sắp xếp List<T> với hàm Sort bên trên, mở rộng hơn so với dùng IComparable là ở đây bạn sẽ sắp xếp với hàm Sort trên khía cạnh nhiều tiêu trí hơn
- Để khai báo các tiêu chí sắp xếp chúng ta sẽ tạo ra 1 class thực thi Interface IComparer để triển khai thuộc tính mà ta sử dụng cho việc sắp xếp thông qua phương thức Compare của interface này, với nhiều tiêu chí khác nhau ta sẽ tạo ra nhiều class thực thi Interface IComparer khác nhau.
- Khi sử dụng hàm Sort ta sẽ truyền 1 tham số là 1 Object được tạo ra từ class thực thi Interface IComparer bên trên.
Bước 1: Kích chuột phải vào Solution chọn Add -> New Project ->Nhập tên (IComparerPerson)-> Chọn OK
Bước 2: Tạo interface có tên Person chứa các thuộc tính
using System;
using System.Collections.Generic;
using System.Text;
namespace IComparablePerson
{
public class Person
{
public int Age { get; set; }
public string Name { get; set; }
}
}
Bước 2: Tạo interface có tên PersonAgeComparer chứa các phương thức
using IComparablePerson;
using System;
using System.Collections.Generic;
using System.Text;
namespace IComparerPerson
{
class PersonAgeComparer: IComparer<Person>
{
public int Compare(Person x, Person y)
{
return x.Age.CompareTo(y.Age);
}
}
}
Bước 3: Tạo interface có tên PersonNameComparer chứa các phương thức
using IComparablePerson;
using System;
using System.Collections.Generic;
using System.Text;
namespace IComparerPerson
{
class PersonNameComparer: IComparer<Person>
{
public int Compare(Person x, Person y)
{
return x.Name.CompareTo(y.Name);
}
}
}
Bước 4: Trong Program code test như sau:
using IComparablePerson;
using System;
using System.Collections.Generic;
using System.Text;
namespace IComparerPerson
{
class Program
{
static void Main(string[] args)
{
Console.OutputEncoding = Encoding.UTF8;
List<Person> personList = new List<Person>();
personList.Add(new Person { Age = 10, Name = "John" });
personList.Add(new Person { Age = 15, Name = "Ann" });
personList.Add(new Person { Age = 8, Name = "Kevin" });
Console.WriteLine("---------Sắp xếp theo tuổi-----------");
personList.Sort(new PersonAgeComparer());
foreach (var item in personList)
{
Console.WriteLine(item.Name + ":" + item.Age);
}
Console.WriteLine("---------Sắp xếp theo tên-----------");
personList.Sort(new PersonNameComparer());
foreach (var item in personList)
{
Console.WriteLine(item.Name + ":" + item.Age);
}
Console.ReadKey();
}
}
}
Bước 5: Nhấn Ctrl+F5 để chạy và xem kết quả
---------Sắp xếp theo tuổi-----------
Kevin:8
John:10
Ann:15
---------Sắp xếp theo tên-----------
Ann:15
John:10
Kevin:8