C# List 排序總結


轉 http://blog.csdn.net/jimo_lonely/article/details/51711821

這里有很多種方法對List進行排序,本文總結了三種方法,但多種實現。

1.對基礎類型排序

方法一:

調用sort方法,如果需要降序,進行反轉:

List<int> list = new List<int>(); list.Sort();// 升序排序 list.Reverse();// 反轉順序

方法二:

使用lambda表達式,在前面加個負號就是降序了

List<int> list= new List<int>(){5,1,22,11,4}; list.Sort((x, y) => x.CompareTo(y));//升序 list.Sort((x, y) => -x.CompareTo(y));//降序

接下來是對非基本類型排序,以一個類為例。


2.准備

首先寫一個類用於排序,里面有兩個屬性,一個構造方法,重寫了ToString方法:

class People
    {
        private int _id; private string _name; public People(int id,string name) { this._id = id; this.Name = name; } public int Id { get { return _id; } set { _id = value; } } public string Name { get { return _name; } set { _name = value; } } //重寫ToString public override string ToString() { return "ID:"+_id+" Name:"+_name; } }

然后添加一些隨機數據,仍希望用Sort排序

        List<People> list = new List<People>(); Random r = new Random(); //添加數據 for(int i = 0; i < 10; i++) { int j = r.Next(0, 10); list.Add(new People(j, "name" + j)); } Console.WriteLine("排序前:"); foreach(var p in list) { Console.WriteLine(p); } list.Sort();//排序 Console.WriteLine("排序后:"); foreach (var p in list) { Console.WriteLine(p); }

很不幸,前面輸出正常,后面拋異常了:

1

查看Sort源碼可知它有如下幾個重載:

2

第三和第四個差不多。

3.實現IComparable接口

4

可以看到它只有一個方法,我們只需要修改類本身

class People: IComparable<People>
    {
        private int _id; private string _name; public People(int id,string name) { this._id = id; this.Name = name; } public int Id { get { return _id; } set { _id = value; } } public string Name { get { return _name; } set { _name = value; } } //重寫的CompareTo方法,根據Id排序 public int CompareTo(People other) { if (null == other) { return 1;//空值比較大,返回1 } //return this.Id.CompareTo(other.Id);//升序 return other.Id.CompareTo(this.Id);//降序 } //重寫ToString public override string ToString() { return "ID:"+_id+" Name:"+_name; } }

 

3

4.實現IComparer接口

我們首先來看看這個接口:

    public interface IComparer<in T> { // Parameters: // x: // The first object to compare. // // y: // The second object to compare. // // Returns: // A signed integer that indicates the relative values of x and y, as shown in the // following table.Value Meaning Less than zerox is less than y.Zerox equals y.Greater // than zerox is greater than y. int Compare(T x, T y); }

 

重點就看返回值,小於0代表x < y,等於0代表x=y,大於0代表x > y.

下面看一下類的實現,非常簡單,一句代碼:

class People:IComparer<People>
    {
        private int _id; private string _name; public People() { } public People(int id,string name) { this._id = id; this.Name = name; } public int Id { get { return _id; } set { _id = value; } } public string Name { get { return _name; } set { _name = value; } } //Compare函數 public int Compare(People x, People y) { return x.Id.CompareTo(y.Id);//升序 } //重寫ToString public override string ToString() { return "ID:"+_id+" Name:"+_name; } }

但是還沒完,我們其實是用了第2點說的第一個重載方法,所以List還需要參數:

            IComparer<People> comparer = new People(); list.Sort(comparer);

 

5.更簡單的

雖然想實現排序上面的接口代碼也不多,但有時候只是偶爾排序,並不像修改類,怎么辦呢?當然有更簡單的方法,委托和lambda表達式:

所以就有了下面的代碼,不需要修改類,只需要用委托構造重載而已:

        list.Sort( delegate(People p1,People p2) { return p1.Id.CompareTo(p2.Id);//升序 } );

當然,lambda表達式實現更簡單:

list.Sort((x,y)=> { return x.Id.CompareTo(y.Id); })

6.OrderBy方法

此方法將排序好的list再賦給原來的list,也可以給其他的。

list = list.OrderBy(o => o.Id).ToList();//升序 list = list.OrderByDescending(o => o.Id).ToList();//降序
  • 1
  • 2
  • 1
  • 2

7.多權重排序

排序的方法我就知道這么多了(其實有更多),接下來還有一個問題,如果希望當ID相同時比較Name,上面的代碼就需要改改了。

其中,接口IComparable這樣寫:

        //重寫的CompareTo方法,根據Id排序 public int CompareTo(People other) { if (null == other) { return 1;//空值比較大,返回1 } //等於返回0 int re = this.Id.CompareTo(other.Id); if (0 == re) { //id相同再比較Name return this.Name.CompareTo(other.Name); } return re; }

 

IComparer和delegate還有lambda里可以這樣:

public int Compare(People x, People y) { int re = x.Id.CompareTo(y.Id); if (0 == re) { return x.Name.CompareTo(y.Name); } return re; }

 

OrderBy方法有點不同:

list = list.OrderBy(o => o.Id).ThenBy(o=>o.Name).ToList(); list = list.OrderByDescending(o => o.Id).ThenByDescending(o=>o.Name).ToList();//降序

8.總結

雖然說了那么多,其實說到底也就三種方法,兩個接口和OrderBy方法,lambda表達式只是讓形式更簡單。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM