Rocky Yu

寻找属于自己的幸福!~

导航

List<T>的排序

Posted on 2010-07-15 13:24  RockyYu  阅读(1390)  评论(4编辑  收藏  举报

多个对象经常需要排序,来满足项目需求。今天简单写个List<T>的排序方法,供日后研究。
先写个学生的类,代码如下:

学生类的代码
 1 /// <summary>
 2 /// 学生类
 3 /// </summary>
 4 public class Student
 5 {
 6     /// <summary>
 7     /// 生成学生对象
 8     /// </summary>
 9     /// <param name="name">姓名</param>
10     /// <param name="age">年龄</param>
11     /// <param name="gender">性别</param>
12     public Student(string name, int age, GenderEnumer gender)
13     {
14         this.name = name;
15         this.age = age;
16         this.gender = gender;
17     }
18     private string name;
19     /// <summary>
20     /// 获取或设置学生的姓名
21     /// </summary>
22     public string Name
23     {
24         get { return this.name; }
25         set { this.name = value; }
26     }
27     private int age;
28     /// <summary>
29     /// 获取或设置学生的年龄
30     /// </summary>
31     public int Age
32     {
33         get { return this.age; }
34         set { this.age = value; }
35     }
36     private GenderEnumer gender;
37     /// <summary>
38     /// 获取或设置学生的性别
39     /// </summary>
40     public GenderEnumer Gender
41     {
42         get { return this.gender; }
43         set { this.gender = value; }
44     }
45 }

 

这里补上一个性别的枚举类型:

1 public enum GenderEnumer
2 {
3     Male = 0,
4     Female = 1
5 }

 

有了学生类,开始创建泛型的集合:

学生集合的代码
1 //创建泛型集合
2 List<Student> students = new List<Student>();
3 students.Add(new Student ("EEE"0GenderEnumer.Male));
4 students.Add(new Student ("DDD"1GenderEnumer.Female));
5 students.Add(new Student ("CCC"2GenderEnumer.Male));
6 students.Add(new Student ("BBB"3GenderEnumer.Female));
7 students.Add(new Student ("AAA"4GenderEnumer.Male));

 

下面我们按照默认的顺序进行输出:

默认顺序输出的代码
1 IEnumerator studentor = students.GetEnumerator();
2 Student student;
3 Console.WriteLine("Default Sort");
4 while (studentor.MoveNext())
5 {
6     student = (Student)studentor.Current;
7     Console.WriteLine("Name:{0}, Age:{1}, Gender:{2}"new object[] { student.Name, student.Age, student.Gender });
8 };

输出如图:

因为要实现List<T>.Sort()所以需要写出IComparer<T>的继承,实现如下:

学生的比较器实现类
 1 /// <summary>
 2 /// 学生的比较器实现类
 3 /// </summary>
 4 public class StudentComparer : IComparer<Student>
 5 {
 6     #region IComparer<Student> 成员
 7 
 8     /// <summary>
 9     /// 泛型比较的实现方法
10     /// </summary>
11     public int Compare(Student x, Student y)
12     {
13         //比较的逻辑,比如return x.Name.CompareTo(y.Name);
14     }
15 
16     #endregion
17 }

添加一个方便以后扩展的枚举,表示进行排序的属性:

1 /// <summary>
2 /// 学生可以比较的属性,也是比较器的类型。
3 /// </summary>
4 public enum StudentComparerType
5 {
6     Name = 0,
7     Age = 1,
8     Gender = 2
9 }

 

修改一下比较方法的实现:

泛型比较的实现方法(第一次修改)
 1 /// <summary>
 2 /// 泛型比较的实现方法(第一次修改)
 3 /// </summary>
 4 public int Compare(Student x, Student y)
 5 {
 6     switch (Type)
 7     {
 8         case StudentComparerType.Name:
 9             return x.Name.CompareTo(y.Name);
10         case StudentComparerType.Age:
11             return x.Age.CompareTo(y.Age);
12         case StudentComparerType.Gender:
13             return x.Gender.CompareTo(y.Gender);
14         default:
15             return 0;
16     }
17 }

 

下面按照学生姓名进行排序:

按照姓名排序的输出代码
1 StudentComparer studentCmp = new StudentComparer(StudentComparerType.Name);
2 students.Sort(studentCmp);
3 studentor = students.GetEnumerator();
4 Console.WriteLine("Name Sort");
5 while (studentor.MoveNext())
6 {
7     student = (Student)studentor.Current;
8     Console.WriteLine("Name:{0}, Age:{1}, Gender:{2}"new object[] { student.Name, student.Age, student.Gender });
9 };

 

 结果输出:

因为也有可能是降序的排序。所以还需要再添加一个排序的方向的枚举:

1 /// <summary>
2 /// 排序的方向,ASC为升序,DESC为降序
3 /// </summary>
4 public enum StudentComparerDirection
5 {
6     ASC = 1,
7     DESC = -1
8 }

 

再次修改比较的实现方法,如下:

泛型比较的实现方法(第二次修改)
 1 /// <summary>
 2 /// 泛型比较的实现方法(第二次修改)
 3 /// </summary>
 4 public int Compare(Student x, Student y)
 5 {
 6     switch (Type)
 7     {
 8         case StudentComparerType.Name:
 9             return (int)Direction * x.Name.CompareTo(y.Name);
10         case StudentComparerType.Age:
11             return (int)Direction * x.Age.CompareTo(y.Age);
12         case StudentComparerType.Gender:
13             return (int)Direction * x.Gender.CompareTo(y.Gender);
14         default:
15             return 0;
16     }
17 }

 

添加一个让学生姓名按照降序排列的输出方法:

按照姓名降序排列的代码
 1 studentCmp = new StudentComparer(StudentComparerType.Name);
 2 studentCmp.Direction = StudentComparerDirection.DESC;
 3 students.Sort(studentCmp);
 4 studentor = students.GetEnumerator();
 5 Console.WriteLine("Name DESC Sort");
 6 while (studentor.MoveNext())
 7 {
 8     student = (Student)studentor.Current;
 9     Console.WriteLine("Name:{0}, Age:{1}, Gender:{2}"new object[] { student.Name, student.Age, student.Gender });
10 };

 

输出的结果如图:

 虽然排序看似不错。但是仅限于单个的排序,如果有属性相同的情况,比如性别这个属性,如图:

所以可能还需要进行二级的排序,甚至多级排序,先写到这,以后再改进。

源码备份地址

/Files/ztlyz/GenericSortTest.rar