zoukankan      html  css  js  c++  java
  • List<T>的排序

    多个对象经常需要排序,来满足项目需求。今天简单写个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

                                   --小小的,有大大的梦想!
  • 相关阅读:
    window 删除文件提示指定的文件名无效或太长
    glib-2.40编译安装
    《Android权威编程指南(The Big Nerd Ranch Guide)(第二版)》12.4挑战练习
    Kotlin中when表达式的使用:超强的switch(KAD 13)
    Kotlin将Realm提升到更高层次
    Kotlin中的“忍者”函数 —— 理解泛型的能力(KAD 12)
    Kotlin中功能操作与集合(KAD 11)
    Kotlin的数据类:节省很多行代码(KAD 10)
    在Android中用Kotlin的Anko运行后台任务(KAD 09)
    Kotlin的扩展函数:扩展Android框架(KAD 08)
  • 原文地址:https://www.cnblogs.com/ztlyz/p/1777951.html
Copyright © 2011-2022 走看看