系列三:C#表达式设计(IComparable和IComparer实现排序)
转自:http://hi.baidu.com/gghost/blog/item/63cc79dd17c24d325882dd1a.html
用List<T>的泛型方法作为试验对象
首先看看LIst<T>.Sort()方法
List<T>.Sort()方法有四种重载
说明
List.Sort ()
使用默认比较器对整个 List 中的元素进行排序。
由 .NET Compact Framework 支持。
List.Sort (泛型 Comparison)
使用指定的 System.Comparison 对整个 List 中的元素进行排序。
由 .NET Compact Framework 支持。
List.Sort (泛型 IComparer)
使用指定的比较器对整个 List 中的元素进行排序。
由 .NET Compact Framework 支持。
List.Sort (Int32, Int32, 泛型 IComparer)
使用指定的比较器对 List 中某个范围内的元素进行排序。
由 .NET Compact Framework 支持。
这次实现Sort()方法的第1,3种重载
public void Sort ()
此方法使用类型 T 的默认比较器 Comparer.Default 确定列表元素的顺序。Comparer.Default 属性检查类型 T 是否实现了 IComparable 泛型接口,如果实现了该接口,则使用该实现。否则,Comparer.Default 将检查类型 T 是否实现了 IComparable 接口。如果类型 T 未实现任一接口,则 Comparer.Default 将引发 InvalidOperationException。
此方法使用 System.Array.Sort,后者使用 QuickSort 算法。此实现执行不稳定排序;亦即,如果两元素相等,则其顺序可能不被保留。相反,稳定排序保留相等元素的顺序。
using System;
using System.Collections.Generic;
using System.Text;
/*您现在准备对员工数组列表(empList)进行排序,为了查看排序是否正常工作,
* 您需要随机地添加整数和Employee实例到它们各自的数组中。创建随机数,需要实例化Random类;
* 调用Random对象的Next()方法产生随机数。Next()方法是一个重载方法;一种版本允许您传递一个整数值,
* 表示您想要的最大随机数。在本例中,您将传递10来产生一个0到10之间的随机数:(译者注:参数为10,最大的随机数只能为9)
*
List<T>.Sort() 此方法使用类型 T 的默认比较器 Comparer.Default 确定列表元素的顺序。
* Comparer.Default 属性检查类型 T 是否实现了 IComparable 泛型接口,如果实现了该接口,则使用该实现。
* 否则,Comparer.Default 将检查类型 T 是否实现了 IComparable 接口。
* 如果类型 T 未实现任一接口,则 Comparer.Default 将引发 InvalidOperationException。
*/
namespace IComparable接口实现
{
class Program
{
static void Main(string[] args)
{
List<Employee> employees = new List<Employee>(5);
Random rd = new Random();
for (int i = 0; i < 5; i++)
{
employees.Add(new Employee(rd.Next(10) + 100));
Console.Write("{0} ", employees[i].ToString());
}
employees.Sort();//排序
//employees.Sort(employees);
Console.WriteLine();
for (int i = 0; i < 5; i++)
{
Console.Write("{0} ", employees[i].ToString());
}
Console.ReadLine();
}
}
#region Employee Class
class Employee : IComparable<Employee>
{
private int emplID;
public int EmoloyeeID
{
get
{
return emplID;
}
}
public Employee(int id)
{
this.emplID = id;
}
public override string ToString()
{
return emplID.ToString();
}
public int CompareTo(Employee other)
{
return this.emplID.CompareTo(other.emplID);
}
public bool Equal(Employee other)
{
return this.emplID == other.emplID ? true : false;
}
}
#endregion
}
public void Sort ( IComparer<T> comparer)
如果提供了 comparer,则 List 的元素是使用指定的 IComparer 实现进行排序的。
如果 comparer 为空引用(在 Visual Basic 中为 Nothing),则默认比较器 Comparer.Default 将检查类型 T 是否实现了 IComparable 泛型接口,如果实现了该接口,则使用该实现。否则,Comparer.Default 将检查类型 T 是否实现了 IComparable 接口。如果类型 T 未实现任一接口,则 Comparer.Default 将引发 InvalidOperationException。
此方法使用 System.Array.Sort,后者使用 QuickSort 算法。此实现执行不稳定排序;亦即,如果两元素相等,则其顺序可能不被保留。相反,稳定排序保留相等元素的顺序。
using System;
using System.Collections.Generic;
using System.Text;
namespace IComparer泛型接口实现
{
class Program
{
static void Main(string[] args)
{
List<EmployeeClass> empList = new List<EmployeeClass>(2);
Random r = new Random();
EmployeeClass ec1 = new EmployeeClass(r.Next(100), r.Next(10));
EmployeeClass ec2 = new EmployeeClass(r.Next(100), r.Next(10));
EmployeeClass ec3 = new EmployeeClass(r.Next(100), r.Next(10));
empList.Add(ec3);
empList.Add(ec1);
empList.Add(ec2);
EmployeeCompareType ect = new EmployeeCompareType(EmployeeCompareType.CompareType.SEV);
empList.Sort(ect);
for (int i = 0; i < empList.Count; i++)
{
Console.WriteLine(empList[i].ToString());
}
Console.ReadLine();
}
}
class EmployeeClass : IComparable<EmployeeClass>
{
private int empID;
private int sevYear;
public EmployeeClass(int empID, int sevYear)
{
this.empID = empID;
this.sevYear = sevYear;
}
public int CompareTo(EmployeeClass ec2)
{
return empID.CompareTo(ec2.empID);
}
public override string ToString()
{
return string.Format("ID:{0,10:D} Year of server:{1}", empID, sevYear);
}
public static int CompareToForType(EmployeeClass ec1, EmployeeClass ec2,EmployeeCompareType.CompareType whichtype)
{
switch (whichtype)
{
case EmployeeCompareType.CompareType.ID:
return ec1.empID.CompareTo(ec2.empID) ;
case EmployeeCompareType.CompareType.SEV:
return ec1.sevYear.CompareTo(ec2.sevYear);
default:
Console.WriteLine("Wrong CompareType");
return 100;
}
}
}
class EmployeeCompareType : IComparer<EmployeeClass>
{
public enum CompareType
{
ID,
SEV
}
public CompareType ComType = CompareType.ID;
public EmployeeCompareType(CompareType ct)
{
this.ComType = ct;
}
public int Compare(EmployeeClass ec1, EmployeeClass ec2)
{
return EmployeeClass.CompareToForType(ec1, ec2, ComType);
}
}
}
以下代码是我自己测试用
//定义一个泛型类型的比较类,实现了IComparer接口,排序时候直接把这个对象的实例传入sort()方法即可,IComparer 的角色是提供附加的比较机制。例如对于您可能需要提供几个字段或属性,在类中的顺序升序和降序在同一字段或两者
public class yulian:IComparer<hhh>
{
#region IComparer<hhh> 成员
int IComparer<hhh>.Compare(hhh x, hhh y)
{
return x.m.CompareTo(y.m);
}
#endregion
}
//在需要进行排序的类型上实现IComparable接口,这样默认的sort()方法能直接调用进行排序
public class hhh:IComparable
{
public string m = null;
public hhh(string n)
{
m = n;
}
#region IComparable 成员,它是类型不安全方法,需要判断类型,并且还需要装箱和拆箱,不建议用
public int CompareTo(object obj)
{
if((obj as hhh).m=="9")//故意设置9为最小元素,9排在第一位
return 2;
return this.m.CompareTo((obj as hhh).m);
}
#endregion
}
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
List<hhh> jihe = new List<hhh>();
jihe.Add(new hhh("9"));
jihe.Add(new hhh("5"));
jihe.Add(new hhh("8"));
jihe.Add(new hhh("6"));
for (int i = 0; i < jihe.Count; i++)//读取未排序数据
{
Response.Write(jihe[i].m);
}
Response.Write("<br/>");
jihe.Sort();//实现默认的排序,也就是在类型中实现了IComparable的方法
for (int i = 0; i < jihe.Count; i++)
{
Response.Write(jihe[i].m);
}
Response.Write("<br/>");
jihe.Sort(new yulian());//辅助类对数组进行的排序,也就是 IComparer的方法排序
for (int i = 0; i < jihe.Count; i++)
{
Response.Write(jihe[i].m);
}

浙公网安备 33010602011771号