這裏有不少種方法對List進行排序,本文總結了三種方法,但有多種實現。javascript
1.對基礎類型排序
方法一:php
調用sort方法,若是須要降序,進行反轉:html
List<int> list = new List<int>(); list.Sort();// 升序排序 list.Reverse();// 反轉順序
方法二:java
使用lambda表達式,在前面加個負號就是降序了less
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));//降序
接下來是對非基本類型排序,以一個類爲例。dom
2.準備
首先寫一個類用於排序,裏面有兩個屬性,一個構造方法,重寫了ToString方法:ide
class People { public People(int id, string name) { this.Id = id; this.Name = name; } public int Id { get; set; } public string Name { get; set; } //重寫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); }
很不幸,前面輸出正常,後面拋異常了:post
查看Sort源碼可知它有以下幾個重載:ui
第三和第四個差很少。
3.實現IComparable接口
能夠看到它只有一個方法,咱們只須要修改類自己
class People: IComparable<People> { public People(int id, string name) { this.Id = id; this.Name = name; } public int Id { get; set; } public string Name { get; set; } //重寫的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> { public People(int id, string name) { this.Id = id; this.Name = name; } public int Id { get; set; } public string Name { get; set; } //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方法
此方法不會改變原始對象中的數據,而是會返回一個新的IOrderedEnumerable<T>對象,能夠將排序好的list再賦給原來的list,也能夠給其餘的對象。
list = list.OrderBy(o => o.Id).ToList();//升序 var listTmp = list.OrderByDescending(o => o.Id).ToList();//降序
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表達式只是讓形式更簡單。