C#中List<T>排序

在面向对象开发过程中我们经常将一组对象放到一个特定集合中,此时我们通常使用泛型集合来存放,常见的如:List、Dictionary等。在使用这些泛型集合时我们有时需要对其进行排序,下面我们就一起学习下List<T>是如何进行排序的。

1.初始化集合

假如我们有一个Student对象,简单起见这个对象只有三个属性,分别是学号、姓名、年龄。

namespace YDSLM_KT_SYSTEM.App_Code.Model
{
    public class Student
    {
        public Student() { }

public Student(string stuNo, string stuName, int stuAge)
        {
            this.StuNo = stuNo;
            this.StuName = stuName;
            this.StuAge = stuAge;
        }

public string StuNo { get; set; }

public string StuName { get; set; }

public int StuAge { get; set; }
    }
}

我们有四个学生,分别存放在List中。

using System;
using System.Collections.Generic;

namespace YDSLM_KT_SYSTEM
{
    public partial class WebForm1 : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            List<App_Code.Model.Student> Students = new List<App_Code.Model.Student>();
            Students.Add(new App_Code.Model.Student("00001", "张三", 17));
            Students.Add(new App_Code.Model.Student("00002", "李四", 16));
            Students.Add(new App_Code.Model.Student("00003", "王五", 18));
            Students.Add(new App_Code.Model.Student("00004", "尔玛", 17));
            Response.Write("未进行排序前:<br />");
            foreach (App_Code.Model.Student stu in Students)
            {

Response.Write(string.Format("学号:{0}&nbsp;&nbsp;&nbsp;姓名:
{1}&nbsp;&nbsp;&nbsp;年龄:{2}<br />", stu.StuNo,
stu.StuName, stu.StuAge));
            }
        }
    }
}

很明显我们往Students对象中加入的时候并没有按年龄顺序,下面我们就一起看一下如何对Students集合按照年龄由小到大来排序。

2.默认排序方式

如果你查一下List<T>的API的话,我们会看到对于List的Sort方法有四种重载,首先在这里我们说一下第一种,也就是无参数的情况:List.Sort()。那么我能不能直接对Students集合使用Sort()方法进行排序呢?答案是否定的,如果我们使用下面的方法排序的话系统将抛出System.ArgumentException异常。

从图中的提示我们可以看出错误原因是由于进行比较的对象并未有任何一个实现IComparable接口,因此也就无法完成排序。事实上对于参数Sort()方法是使用Comparer.Default比较器来排序的,而此比较器进行比较时首先就会检查T是否实现了IComparable泛型接口,如果实现了则使用该实现。否则将坚持是否实现了IComparable接口。如果均未实现则引发InvalidOperationException异常。也就是说如果想使用此方法需要实现IComara泛型接口或者IComparable接口,因此我们暂且修改一下Student类,实现IComparable接口(除了这个例子职务后面的例子仍然使用第一步我们建立的Student类)。

首先修改Student类,实现IComparable接口:

using System;

namespace YDSLM_KT_SYSTEM.App_Code.Model
{
    public class Student : IComparable
    {
        public Student() { }

public Student(string stuNo, string stuName, int stuAge)
        {
            this.StuNo = stuNo;
            this.StuName = stuName;
            this.StuAge = stuAge;
        }

public string StuNo { get; set; }

public string StuName { get; set; }

public int StuAge { get; set; }

#region IComparable接口成员
        public int CompareTo(object obj)
        {
            if (obj is Student)
            {
                Student tempStu = obj as Student;
                return this.StuAge.CompareTo(tempStu.StuAge);
            }
            throw new NotImplementedException("obj is not a Student!");
        }
        #endregion
    }
}

然后我们再运行程序就会看到可以按照我们的想法去排序了。

接着再使用Sort()排序的话就可以看到如下排序成功的界面:

3.通过自定义比较器进行排序

尽管我们上面说过可以使用Sort()方法排序,但是要求Student必须实现IComparable泛型接口,那么我们有没有其他的方法呢?其实是有的,个人感觉这种方法多数情况下会更好一些。那就是:List.Sort(泛型Comparison)和List.Sort(泛型IComparer)方法。之所以将这两种重载放到一起来说,是因为二者使用范围上很类似。首先看一下List.Sort(泛型Comparison)方法,此方法的参数是Comparison类型,其实是一个包含两个参数的委托,因此使用此方法,我们只需要定义一个委托,其两个参数均为Student类型,在委托实现的方法比较两个Student对象Age属性即可。

using System;
using System.Collections.Generic;

namespace YDSLM_KT_SYSTEM
{
    public partial class WebForm1 : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            List<App_Code.Model.Student> Students = new List<App_Code.Model.Student>();
            Students.Add(new App_Code.Model.Student("00001", "张三", 17));
            Students.Add(new App_Code.Model.Student("00002", "李四", 16));
            Students.Add(new App_Code.Model.Student("00003", "王五", 18));
            Students.Add(new App_Code.Model.Student("00004", "尔玛", 17));
            Response.Write("未进行排序前:<br />");
            foreach (App_Code.Model.Student stu in Students)
            {
                Response.Write(string.Format("学号:{0}&nbsp;&nbsp;&nbsp;姓名:{1}&nbsp;&nbsp;&nbsp;年龄:{2}<br />", stu.StuNo, stu.StuName, stu.StuAge));
            }
            Response.Write("使用List.Sort(泛型Comparison)排序之后:<br />");
            Students.Sort(delegate(App_Code.Model.Student a, App_Code.Model.Student b)
            {
                return a.StuAge.CompareTo(b.StuAge);
            });
            foreach (App_Code.Model.Student stu in Students)
            {
                Response.Write(string.Format("学号:{0}&nbsp;&nbsp;&nbsp;姓名:{1}&nbsp;&nbsp;&nbsp;年龄:{2}<br />", stu.StuNo, stu.StuName, stu.StuAge));
            }
        }
    }
}

运行结果(注意:此时以及下面的所有例子中Student均不需要实现IComparable泛型接口):

接着我们看一下List.Sort(泛型IComparer),此方法需要一个泛型IComparer接口类型,因此只要定义一个类实现此接口然后再调用此方法即可。

using System.Collections.Generic;

namespace YDSLM_KT_SYSTEM.App_Code
{
    public class StudentCompare:IComparer<Model.Student>
    {

public int Compare(Model.Student x, Model.Student y)
        {
            return x.StuAge.CompareTo(y.StuAge);
        }
    }
}

-----------------------------------------------------

using System;
using System.Collections.Generic;

namespace YDSLM_KT_SYSTEM
{
    public partial class WebForm1 : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            List<App_Code.Model.Student> Students = new List<App_Code.Model.Student>();
            Students.Add(new App_Code.Model.Student("00001", "张三", 17));
            Students.Add(new App_Code.Model.Student("00002", "李四", 16));
            Students.Add(new App_Code.Model.Student("00003", "王五", 18));
            Students.Add(new App_Code.Model.Student("00004", "尔玛", 17));
            Response.Write("未进行排序前:<br />");
            foreach (App_Code.Model.Student stu in Students)
            {
                Response.Write(string.Format("学号:{0}&nbsp;&nbsp;&nbsp;姓名:{1}&nbsp;&nbsp;&nbsp;年龄:{2}<br />", stu.StuNo, stu.StuName, stu.StuAge));
            }
            Response.Write("使用List.Sort (泛型 IComparer) 排序之后:<br />");
            Students.Sort(new App_Code.StudentCompare());
            foreach (App_Code.Model.Student stu in Students)
            {
                Response.Write(string.Format("学号:{0}&nbsp;&nbsp;&nbsp;姓名:{1}&nbsp;&nbsp;&nbsp;年龄:{2}<br />", stu.StuNo, stu.StuName, stu.StuAge));
            }
        }
    }
}

运行结果:

4.设定排序范围

虽然上面的方法都实现了泛型List<T>集合排序,但是有时我们并不需要对整个集合进行排序而是指对其中一定范围的对象进行排序,那么我们就需要使用Sort方法的第四种重载:List.Sort(int32,int32,泛型IComparer)。前两个参数分别代表排序的其实位置和排序长度,最后一个参数仍然是泛型IComparer接口类型。上面我们已经定义了StudentComparer类,实现了IComparer接口,这里就可以直接使用了,下面我们只对前三个学生按年龄由小到大进行排序。

using System;
using System.Collections.Generic;

namespace YDSLM_KT_SYSTEM
{
    public partial class WebForm1 : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            List<App_Code.Model.Student> Students = new List<App_Code.Model.Student>();
            Students.Add(new App_Code.Model.Student("00001", "张三", 17));
            Students.Add(new App_Code.Model.Student("00002", "李四", 16));
            Students.Add(new App_Code.Model.Student("00003", "王五", 18));
            Students.Add(new App_Code.Model.Student("00004", "尔玛", 17));
            Response.Write("未进行排序前:<br />");
            foreach (App_Code.Model.Student stu in Students)
            {
                Response.Write(string.Format("学号:{0}&nbsp;&nbsp;&nbsp;姓名:{1}&nbsp;&nbsp;&nbsp;年龄:{2}<br />", stu.StuNo, stu.StuName, stu.StuAge));
            }
            Response.Write("使用List.Sort (Int32, Int32, 泛型 IComparer) 排序之后:<br />");
            Students.Sort(0, 3, new App_Code.StudentCompare());
            foreach (App_Code.Model.Student stu in Students)
            {
                Response.Write(string.Format("学号:{0}&nbsp;&nbsp;&nbsp;姓名:{1}&nbsp;&nbsp;&nbsp;年龄:{2}<br />", stu.StuNo, stu.StuName, stu.StuAge));
            }
        }
    }
}

运行效果:

到这里我和大家一起学习分享完毕了,期望对大家也有些帮助!!!

C#中List<T>排序

时间: 2024-10-11 04:44:35

C#中List<T>排序的相关文章

MySQL中order by排序时,数据存在null咋办

order by排序是最常用的功能,但是排序有时会遇到数据为空null的情况,这样排序就会乱了,这里以MySQL为例,记录我遇到的问题和解决思路. 问题: 网页要实现table的行鼠标拖拽排序,我用AngularJs集成了一个TableDnD开源插件,可以实现,然后在数据库表中增加一个排序字段indexId,但是原来的大量数据是没有排序过的,所以该字段为null. 这样order by时,为null的数据就会排在最前边. 写个测试表模拟一下,如下效果: 解决办法: 最优办法:利用MySQL中的一

Basic4Android中按日期排序文件

#Region Project Attributes #ApplicationLabel: SortByDateFileTest #VersionCode: 20140627 #VersionName: 'SupportedOrientations possible values: unspecified, landscape or portrait. #SupportedOrientations: unspecified #CanInstallToExternalStorage: False

关于Oracle数据库中SQL空值排序的问题

在Oracle中进行查询排序时,如果排序字段里面有空值的情况下,排序结果可能会达不到自己想要的结果. 如 select * from tableTest order by VISITS desc 将原来的sql语句改写为:select * from tableTest order by VISITS desc nulls last,"nulls last"控制将空值记录放在后面,当然,你也可以用"nulls first"将控制记录放在前面. oracle 空值处理,

C实现数组中元素的排序

使用C实现数组中元素的排序,使得数组中的元素从小到大排列.只不过在这个过程中出了一点小问题,在C中进行数字交换的时候,必须要使用指针的,不能使用引用.在后面的文章中,我要学习一个在C中的引用和指针的区别.下面看一下我的代码吧. #include <stdio.h> void swap(int *a,int *b); void rest(int lels[],int count); /** * 该实例用于实现对用户输入的数组进行排序 * 要求的数组中的元素从小到大来咧 * * @brief ma

DataSet 中的数据排序 及 DataRow装成DataTable

1.DataSet 中的数据排序 DataSet ds = new DataSet(); // 获取当前排口的数据 ds = _xiaobill.GetHistoryData(yinZiBianm, zhanDian, beginDate, endDate, dNum); DataTable dt = ds.Tables[0]; DataRow[] dt2 = dt.Select("1=1","数据时间 ASC "); DataRow[]装成DataTable Da

Android中ListView字母排序,实现字母挤压效果以及右侧快速选中字母,搜索关键字功能

Android中ListView字母排序,实现字母挤压效果以及右侧快速选中字母,搜索关键字功能 本文中阐述如何自定义EditText实现搜索框自定义的样式以及挤压字母的思路等 自定义EditText 相关的drawable文件 主界面以及相关的适配器 结果展示 定义要呈现的EditText的样式 public class ClearEditText extends EditText implements OnFocusChangeListener, TextWatcher { /** * 定义删

网页中的信息排序信息显示

平常我们在浏览网页的时候,经常会见到下图所示的列表信息. 那么今天我们就来学习下网页中的信息排序显示 列表标记 1.    标记的用途 列表标记可以创建一般的无序列表.编号列表,以及定义列表三种方式.还可以在一种列表中嵌套另一种列表,便于概括显示一系列相关的内容. 2.    无序列表 语法: <ul type="项目符号类型"> <li type="项目符号类型">内容1</li> - </ul> 牛刀小试 <

STL中的各种排序函数

标准c++库中提供六种排序方法:qsort(),  sort(),stable_sort(),  partial_sort(),  list::sort(),  set/multiset qsort()比sort()慢并且不能排序构造函数.虚函数,一般不推荐使用.写一个比较函数传递给qsort()很麻烦: 后五个排序中,前三个是泛型算法,后两个则使用了某些容器的特别特性.所有的这些都是使用operator()来比较对象,但是在必要时指定用户自己的比较函数. 后五个每个都提供了自己的特征: 1.s

C/C++中的经典排序算法总结

C/C++中的经典排序算法总结 在C/C++中,有一些经典的排序算法,例如:冒泡排序.鸡尾酒排序或双向冒泡排序(改进的冒泡排序).选择排序.直接插入排序.归并排序.快速排序.希尔排序和堆排序等等.下面对这些排序算法进行一一解析并给出示例代码以共享之. 1.冒泡排序 冒泡排序是最基本的排序算法,之所以称之为冒泡排序是因为在冒泡排序的过程中总是大数往前放,小数往后放,相当于气泡上升. 冒泡排序的基本原理是:依次比较相邻的两个数,将大数放在前面,小数放在后面. 影响冒泡排序算法性能的主要部分就是循环和