本文摘要:
1:比較和排序的概念;
2:IComparable和IComparer;
3:IComparable和IComparer的泛型實現IComparable<T>和IComparer<T>;
1:比較和排序的概念
比較:兩個實體類之間按>,=,<進行比較。
排序:在集合類中,對集合類中的實體進行排序。排序基於的算法基於實體類提供的比較函數。
基本型別都提供了默認的比較算法,如string提供了按字母進行比較,int提供了按整數大小進行比較。
2:IComparable和IComparer
當我們創建了自己的實體類,如Student,默認想要對其按照年齡進行排序,則需要為實體類實現IComparable接口。
class Student:IComparable
{
public string Name { get; set; }
public int Age { get; set; }
#region IComparable Members
public int CompareTo(object obj)
{
Student student = obj as Student;
if (Age > student.Age)
{
return 1;
}
else if (Age == student.Age)
{
return 0;
}
else
{
return -1;
}
//return Age.CompareTo(student.Age);
}
#endregion
}
PS:注意上面代碼中CompareTo方法有一條注釋的代碼,其實本函數完全可以使用該注釋代碼代替,因為利用了整形的默認比較方法。此處未使用本注釋代碼,是為了更好的說明比較器的工作原理。 接下來寫一個測試用例: public Form1()
{
InitializeComponent();
studentList = new ArrayList();
studentList.Add(new Student() { Age = 1, Name = "a1" });
studentList.Add(new Student() { Age = 5, Name = "g1" });
studentList.Add(new Student() { Age = 4, Name = "b1" });
studentList.Add(new Student() { Age = 2, Name = "f1" });
}
ArrayList studentList;
private void button1_Click(object sender, EventArgs e)
{
studentList.Sort();
foreach (Student item in studentList)
{
this.textBox1.Text += item.Name + "----" +item.Age.ToString() + "
" ;
}
}
運行結果:
a1----1
f1----2
b1----4
g1----5
OK,疑問來了。如果不想使用年齡作為比較器了,那怎麼辦。這個時候IComparer的作用就來了,可使用IComparer來實現一個自定義的比較器。如下:
class SortName: IComparer
{
#region IComparer Members
public int Compare(object x, object y)
{
Student s1 = x as Student;
Student s2 = y as Student;
return s1.Name.CompareTo(s2.Name);
}
#endregion
}
這個時候,我們在排序的使用為Sort方法提供此比較器:
studentList.Sort(new SortName());
運行的結果是:
a1----1
b1----4
f1----2
g1----5
3:IComparable和IComparer的泛型實現IComparable<T>和IComparer<T>
如果我們稍有經驗,我們就會發現上面的代碼我們使用了一個已經不建議使用的集合類ArrayList。當泛型出來後,所有非泛型集合類已經建議不盡量使用了。至於原因,從上面的代碼中我們也可以看出一點端倪。
注意查看這個Compare函數,如:
public int Compare(object x, object y)
{
Student s1 = x as Student;
Student s2 = y as Student;
return s1.Name.CompareTo(s2.Name);
}
我們發現這個函數進行了裝箱和拆箱。而這是會影響性能的。如果我們的集合中有成千上萬個復雜的實體對象,則在排序的時候所耗費掉的性能就是客觀的。而泛型的出現,就可以避免掉拆箱和裝箱。
故上文代碼中的ArrayList,應該換成List<T>,對應的,我們就該實現IComparable<T>和IComparer<T>。最終的代碼應該像:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
studentList = new List<Student>();
studentList.Add(new Student() { Age = 1, Name = "a1" });
studentList.Add(new Student() { Age = 5, Name = "g1" });
studentList.Add(new Student() { Age = 4, Name = "b1" });
studentList.Add(new Student() { Age = 2, Name = "f1" });
&nb