比较和排序(IComparable和IComparer以及它们的泛型实现)
2011-02-10 10:30
357 查看
本文摘要:
1:比较和排序的概念;
2:IComparable和IComparer;
3:IComparable和IComparer的泛型实现IComparable<T>和IComparer<T>;
1:比较和排序的概念
比较:两个实体类之间按>,=,<进行比较。
排序:在集合类中,对集合类中的实体进行排序。排序基于的算法基于实体类提供的比较函数。
基本型别都提供了默认的比较算法,如string提供了按字母进行比较,int提供了按整数大小进行比较。
2:IComparable和IComparer
当我们创建了自己的实体类,如Student,默认想要对其按照年龄进行排序,则需要为实体类实现IComparable接口。
运行结果:
a1----1
f1----2
b1----4
g1----5
OK,疑问来了。如果不想使用年龄作为比较器了,那怎么办。这个时候IComparer的作用就来了,可使用IComparer来实现一个自定义的比较器。如下:
这个时候,我们在排序的使用为Sort方法提供此比较器:
studentList.Sort(new SortName());
运行的结果是:
a1----1
b1----4
f1----2
g1----5
3:IComparable和IComparer的泛型实现IComparable<T>和IComparer<T>
如果我们稍有经验,我们就会发现上面的代码我们使用了一个已经不建议使用的集合类ArrayList。当泛型出来后,所有非泛型集合类已经建议不尽量使用了。至于原因,从上面的代码中我们也可以看出一点端倪。
注意查看这个Compare函数,如:
我们发现这个函数进行了装箱和拆箱。而这是会影响性能的。如果我们的集合中有成千上万个复杂的实体对象,则在排序的时候所耗费掉的性能就是客观的。而泛型的出现,就可以避免掉拆箱和装箱。
故上文代码中的ArrayList,应该换成List<T>,对应的,我们就该实现IComparable<T>和IComparer<T>。最终的代码应该像:
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() + "/r/n" ;
}
}
运行结果:
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" }); } List<Student> studentList; private void button1_Click(object sender, EventArgs e) { studentList.Sort(new SortName()); foreach (Student item in studentList) { this.textBox1.Text += item.Name + "----" +item.Age.ToString() + "/r/n" ; } } } class Student:IComparable<Student> { public string Name { get; set; } public int Age { get; set; } #region IComparable<Student> Members public int CompareTo(Student other) { return Age.CompareTo(other.Age); } #endregion } class SortName: IComparer<Student> { #region IComparer<Student> Members public int Compare(Student x, Student y) { return x.Name.CompareTo(y.Name); } #endregion }
相关文章推荐
- 比较和排序(IComparable和IComparer以及它们的泛型实现)
- 比较和排序(IComparable和IComparer以及它们的泛型实现)
- C#笔记25:比较和排序(IComparable和IComparer以及它们的泛型实现)
- 比较和排序(IComparable和IComparer以及它们的泛型实现)
- 比较和排序(IComparable和IComparer以及它们的泛型实现)
- 比较和排序(IComparable和IComparer以及它们的泛型实现)
- 比较和排序(IComparable和IComparer以及它们的泛型实现)
- C#笔记25:比较和排序(IComparable和IComparer以及它们的泛型实现)
- 比较和排序(IComparable和IComparer以及它们的泛型实现)
- 比较和排序(IComparable和IComparer以及它们的泛型实现)
- 比较和排序(IComparable和IComparer以及它们的泛型实现)
- 计数排序、选择排序、冒泡排序、插入排序的实现以及它们的比较次数和移动次数
- 对象的比较与排序(二):实现IComparable和IComparer接口 和 Comparer类(转)
- 对象的比较与排序(二):实现IComparable和IComparer接口 和 Comparer类
- Effective C# 使用IComparable和IComparer接口实现排序关系
- C#中的IComparable 和 IComparer 接口,实现列表中的对象比较和排序
- 通用的泛型Icomparer生成类,对类进行排序,最大支持4个字段同时比较
- 通用的泛型Icomparer生成类,对类进行排序,最大支持4个字段同时比较
- 堆排序的C语言实现以及和快排的比较
- Effective C# 使用IComparable和IComparer接口实现排序关系