轉 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); }
很不幸,前面輸出正常,后面拋異常了:
查看Sort源碼可知它有如下幾個重載:
第三和第四個差不多。
3.實現IComparable接口
可以看到它只有一個方法,我們只需要修改類本身
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; } }
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表達式只是讓形式更簡單。