`

C# List 排序

 
阅读更多

C# List 排序

    摘要:在面向对象开发过程中我们经常将一组对象放到一个特定集合中,此时我们通常使用泛型集合来存放,常见的如:List Dictionary等。在使用这些泛型集合时我们有时需要对其进行排序,下面我们就一块看一下List如何进行排序(像Dictionary也有其相应的排序方式,例如说使用Linq语法方式,今天暂且不说)。

主要内容:

1.  初始工作

2.  默认排序方式

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

4.  设定排序范围

5.  总结

一、初始工作

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

 

代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace GenericCompare
{
    class Student
    {
        public Student()
        {
        }
        public Student(string no, string name, int age)
        {
            this.No = no;
            this.Name = name;
            this.Age = age;
        }
        public string No
        {
            get;
            set;
        }
        public string Name
        {
            get;
            set;
        }
        public int Age
        {
            get;
            set;
        }
    }
}

 

 

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

 

代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace GenericCompare
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Student> students = new List<Student>();
            students.Add(new Student("001","kenshincui",25));
            students.Add(new Student("002", "miaoer", 23));
            students.Add(new Student("003", "shenjinjuan", 22));
            students.Add(new Student("004", "nieyanxin", 24));
            Console.WriteLine("
未进行排序之前:");
            foreach (Student st in students)
            {
                Console.WriteLine(st.No+","+st.Name+","+st.Age+";");
            }
            Console.ReadKey();
        }
    }
}

 

 

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

二、默认排序方式

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

 

代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace GenericCompare
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Student> students = new List<Student>();
            students.Add(new Student("001","kenshincui",25));
            students.Add(new Student("002", "miaoer", 23));
            students.Add(new Student("003", "shenjinjuan", 22));
            students.Add(new Student("004", "nieyanxin", 24));
            Console.WriteLine("
未进行排序之前:");
            foreach (Student st in students)
            {
                Console.WriteLine(st.No+","+st.Name+","+st.Age+";");
            }
            Console.WriteLine("List.Sort ()
排序之后:");
            students.Sort();
            foreach (Student st in students)
            {
                Console.WriteLine(st.No + "," + st.Name + "," + st.Age + ";");
            }
            Console.ReadKey();
        }
    }
}

 

 

执行上面的代码将抛出如下异常

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

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

 

代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace GenericCompare
{
    class Student:IComparable
    {
        public Student()
        {
        }
        public Student(string no, string name, int age)
        {
            this.No = no;
            this.Name = name;
            this.Age = age;
        }
        public string No
        {
            get;
            set;
        }
        public string Name
        {
            get;
            set;
        }
        public int Age
        {
            get;
            set;
        }
        #region IComparable
成员
        public int CompareTo(object obj)
        {
            if (obj is Student)
            {
                Student tempStudent = obj as Student;
                return this.Age.CompareTo(tempStudent.Age);
            }
            throw new NotImplementedException("obj is not a Student!");
        }
        #endregion
    }
}

 

 

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

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

三、通过自定义比较器进行排序

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

 

代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace GenericCompare
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Student> students = new List<Student>();
            students.Add(new Student("001","kenshincui",25));
            students.Add(new Student("002", "miaoer", 23));
            students.Add(new Student("003", "shenjinjuan", 22));
            students.Add(new Student("004", "nieyanxin", 24));
            Console.WriteLine("
未进行排序之前:");
            foreach (Student st in students)
            {
                Console.WriteLine(st.No+","+st.Name+","+st.Age+";");
            }
            Console.WriteLine("List.Sort (
泛型 Comparison) 排序之后:");
            students.Sort(delegate(Student a, Student b) { return a.Age.CompareTo(b.Age); });
            foreach (Student st in students)
            {
                Console.WriteLine(st.No + "," + st.Name + "," + st.Age + ";");
            }
            Console.ReadKey();
        }
    }
}

 

 

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

 

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

代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace GenericCompare
{
    class StudentCompare :IComparer<Student>
    {
        public int Compare(Student a, Student b)
        {
            return a.Age.CompareTo(b.Age);
        }
    }
}

 

 

代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace GenericCompare
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Student> students = new List<Student>();
            students.Add(new Student("001","kenshincui",25));
            students.Add(new Student("002", "miaoer", 23));
            students.Add(new Student("003", "shenjinjuan", 22));
            students.Add(new Student("004", "nieyanxin", 24));
            Console.WriteLine("
未进行排序之前:");
            foreach (Student st in students)
            {
                Console.WriteLine(st.No+","+st.Name+","+st.Age+";");
            }
            Console.WriteLine("List.Sort (
泛型 IComparer) 排序之后:");
            students.Sort(new StudentCompare());
            foreach (Student st in students)
            {
                Console.WriteLine(st.No + "," + st.Name + "," + st.Age + ";");
            }
            Console.ReadKey();
        }
    }
}

 

 

运行效果:

四、设定排序范围

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

 

代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace GenericCompare
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Student> students = new List<Student>();
            students.Add(new Student("001","kenshincui",25));
            students.Add(new Student("002", "miaoer", 23));
            students.Add(new Student("003", "shenjinjuan", 22));
            students.Add(new Student("004", "nieyanxin", 24));
            Console.WriteLine("
未进行排序之前:");
            foreach (Student st in students)
            {
                Console.WriteLine(st.No+","+st.Name+","+st.Age+";");
            }
            Console.WriteLine("List.Sort (Int32, Int32,
泛型 IComparer) 排序之后:");
            students.Sort(0, 3, new StudentCompare());
            foreach (Student st in students)
            {
                Console.WriteLine(st.No + "," + st.Name + "," + st.Age + ";");
            }
            Console.ReadKey();
        }
    }
}

 

 

运行效果:

五、总结:

对于List的排序,.Net中给我们提供了很多选择,我们可以根据情况灵活使用。关于其他泛型集合的排序(例如Dictionary)有时间的话我后面也会逐一同大家分享,今天暂且到这里吧

 

 

1
2
分享到:
评论

相关推荐

    c# List类排序方法

    ### c# List类排序方法 #### 一、初始工作与预备知识 在C#中,`List&lt;T&gt;`是一个非常常用的泛型集合类,它提供了动态数组的功能,可以存储任意数量的相同类型元素。当涉及到对List中的数据进行排序时,我们可以采用...

    C# List OrderBy 动态多字段排序

    在C#编程中,`List&lt;T&gt;` 是一个常用的集合类,用于存储同类型的元素序列。在处理这些数据时,我们经常需要对它们进行排序。`OrderBy` 方法是 LINQ(Language Integrated Query) 提供的一个非常方便的排序工具,它...

    C#对list列表进行随机排序的方法

    总的来说,C#中对list列表进行随机排序的方法主要依赖于随机数生成器,通过生成随机索引并插入元素,可以轻松实现列表的随机化。这种技巧在各种场景中都很有用,比如模拟随机事件、游戏中的随机生成等。希望这个方法...

    分页控件和List绑定排序

    在IT行业中,分页控件和列表数据绑定是常见的数据展示技术,...综上所述,自定义分页控件和List绑定排序是提升数据展示效率的关键技术。通过理解和掌握这些知识点,开发者可以为用户提供更加高效、友好的数据浏览体验。

    C#属性排序 List Dictionary

    C# 多个属性排序 List Dictionary 升序降序 可以同时包含升序降序 一个类中 按属性A降序 ,然后按属性B升序 ,最后按照属性C降序

    CSharp_List.zip_C# list_C#中list_C#中list的用法_C#怎么引用List_c# list

    在C#编程中,`List&lt;T&gt;`是.NET框架中常用的一种动态数组,它属于泛型集合,提供了丰富的功能,使得在处理一系列数据时更加灵活高效。`List&lt;T&gt;`类是`System.Collections.Generic`命名空间的一部分,它实现了`IList&lt;T&gt;`...

    C# xml处理和排序

    - **排序后的XML保存**:对List排序后,可以将其数据保存回XML文件,确保元素按照新的顺序排列。 通过以上方法,C#开发者可以高效地处理XML文档,同时利用List的排序功能对数据进行组织和管理。在实际项目中,这两...

    C# List 排序各种用法与比较

    在C#编程中,`List&lt;T&gt;` 是一个常用的集合类型,它提供了丰富的操作方法,包括排序功能。本文将详细介绍三种不同的方法对C#中的`List&lt;T&gt;`进行排序,并比较它们的适用性和优缺点。 首先,我们创建了一个`People`实体...

    c# 实现按拼音排序

    在C#编程中,对汉字进行拼音排序是一个常见的需求,特别是在处理中文数据时。这个任务主要涉及以下几个关键知识点: 1. **汉字转拼音**:在C#中,我们需要一个库或者方法来将汉字转换为对应的拼音。这通常通过.NET ...

    C#快速排序练习

    在C#中实现快速排序,可以创建一个`QuickSort`方法,接收一个整数数组和两个整数参数,分别代表要排序的子数组的起始和结束索引。这里是一个简单的C#实现示例: ```csharp public static void QuickSort(int[] ...

    c# ObservableCollection排序

    相对于System.Linq的OrderBy及OrderByDescending方法,调用后产生IOrderedEnumberable对象,这个对象为排序后的返回值,但原对象未发生变化。试想,有这种需求,ObservableCollection调用排序方法后,此对象也跟着...

    C#list集合按元素出现次数排序取值(含去重功能)

    此文件搭配本人发表的文章:C#list集合按元素出现次数排序取值(含去重功能),资源完全免费下载,不收取任何费用,纯粹的技术交流。联系方式在文章中有,喜欢的朋友们可以互相交流一下。

    C#对控件进行排序

    在C#中,我们可以使用`Array`或`List&lt;T&gt;`等数据结构来辅助实现控件的排序。以下是一种常见的方法: 1. 将`Panel`的`Controls`集合转换为`List&lt;Control&gt;`。这可以通过`Controls.Cast().ToList()`完成,这样我们就...

    c#对list排序示例

    namespace ListSort { class Program { static void Main(string[] args) { List listCustomer = new List(); listCustomer.Add(new Customer { name = “客户1”, id = 0 }); listCustomer.Add(new Customer { ...

    C# DataGridView多列排序(多列排序要按住Shift键).zip

    一种常见的优化策略是将数据存储在内存中的数据结构(如`List&lt;T&gt;`或`DataTable`)中,并仅对这部分数据进行排序,而不是每次都从数据库重新加载所有数据。此外,还可以通过异步处理排序来避免阻塞UI线程。 总的来说...

    字典 自动排序 c#

    总结来说,要在C#中实现字典自动排序,可以通过转换为`List`并使用Linq的排序方法,或者使用内置的`SortedList`和`SortedDictionary`类。同时,根据用户输入实时更新排序结果,需要监听输入事件并进行相应的处理。在...

    队列排序实例 C#

    在C#中,`System.Collections.Generic`命名空间提供了许多内置的排序工具,如`Array.Sort()`、`List&lt;T&gt;.Sort()`以及`Enumerable.OrderBy()`等。这些方法通常会提供比自定义排序算法更好的性能,特别是在处理大数据集...

    c#经典排序

    6. **并行和异步排序**:在处理大数据集时,C#提供了并行排序(`Parallel.Sort()`)和异步排序(`Task.Run(() =&gt; list.Sort())`)的功能,利用多核处理器的计算能力提高排序速度。 7. **性能分析**:了解不同排序...

Global site tag (gtag.js) - Google Analytics