重温算法与数据结构:(1)排序算法的预备知识
谈起排序,势必会想到比较。在.NET框架中什么和比较有关系呢?自然是IComparable、IComparable<T>、IComparer<T>、IEqualityComparer<T>这几个接口,其中IComparable<T>为IComparable的泛型版本。泛型的优点自然不必多说。在一切有可能的情况,我们应该优先使用泛型。老赵的这篇文章可以回答你有关泛型性能的问题。
.NET框架中的IComparable、IComparable<T>、IComparer<T>、IEqualityComparer<T>
它们的的定义如下:
public interface IComparer<T> { int Compare(T x, T y); } public interface IComparable { int CompareTo(object obj); } public interface IComparable<T> { int CompareTo(T other); } public interface IEqualityComparer<T> { bool Equals(T x, T y); int GetHashCode(T obj); }
对于特定类型实现IComparer<T>接口,这样当你在实现排序算法时,即可调用IComparer<T>.Compare(T x, T y)进行对实例x,y的比较,方法返回值小于0,表明x小于y,若返回值等于0,表明x等于y,若返回值大于0,表明x大于y。对于IComparable<T>接口,当某类型实现该接口时,就可以再该类型实例上调用CompareTo(T other)方法,方法返回值小于0,表明实例小于other参数,若返回值等于0,表明实例等于other参数,若返回值大于0,表明实例大于other参数。对于IEqualityComparer<T>接口,可以根据对该接口的实现类,调用Equals(T x, T y)方法,返回true表明x和y相等。
通过实现接口IComparable<Employee>:
现在准备一个雇员类,内含三个成员(年龄、姓名、所在部门),根据年龄大小来判断大小,年龄大的雇员大于年龄小的雇员。代码如下:
public class Employee : IComparable<Employee> { public int Age { get; set; } public string Name { get; set; } public string Department { get; set; } public Employee(int age,string name,string department) { this.Age = age; this.Name = name; this.Department = department; } #region IComparable<Employee> Members public int CompareTo(Employee other) { return this.Age - other.Age; } #endregion }
测试代码:
static void Main(string[] args) { Employee anders = new Employee(35, "Anders Wang", "Developer Division"); Employee jeffrey = new Employee(28, "Jeffrey Chen", "Developer Division"); Employee steve = new Employee(35, "Anders Wang", "Developer Division"); Console.WriteLine(anders.CompareTo(jeffrey)); //output > 0 }
从Employee的CompareTo看出,由于anders的Age>jeffrey的Age,所以anders.CompareTo(jeffrey)返回1,表明实例anders大于实例jeffrey。
通过实现接口IComparer<Employee>:
代码如下:
class EmployeeComparer:IComparer<Employee> { #region IComparer<Employee> Members public int Compare(Employee x, Employee y) { return x.Age - y.Age; } #endregion }
测试代码:
static void Main(string[] args) { Employee anders = new Employee(35, "Anders Wang", "Developer Division"); Employee jeffrey = new Employee(28, "Jeffrey Chen", "Developer Division"); Employee steve = new Employee(35, "Anders Wang", "Developer Division"); Console.WriteLine(new EmployeeComparer().Compare(anders, jeffrey)); //output > 0 }
以上代码也同样实现了比较功能。
通过实现接口IEqualityComparer<Employee>:
要判断两个对象是否相等?我们可以通过实现IEqualityComparer<T>接口或者通过调用基类object的Equals方法。但是在大部分情况下,调用基类object的Equals方法需要进行强制转换,含有类型不安全的问题。下面我们通过EmployeeEqualityComparer来实现IEqualityComparer<T>。代码如下:
public class EmployeeEqualityComparer:IEqualityComparer<Employee> { #region IEqualityComparer<Employee> Members public bool Equals(Employee x, Employee y) { if (x.Age == y.Age && x.Name == y.Name && x.Department == y.Department) { return true; } return false; } public int GetHashCode(Employee obj) { //由于是根据Age,Name,Department来进行判等的, //所以哈希值的求取过程也要进行一定的修改, //确保相等对象的哈希值也是相等的。 //在类型Employee内部覆盖GetHashCode方法即可。 return obj.GetHashCode(); } #endregion }
测试代码:
static void Main(string[] args) { Employee anders = new Employee(35, "Anders Wang", "Developer Division"); Employee jeffrey = new Employee(28, "Jeffrey Chen", "Developer Division"); Employee steve = new Employee(35, "Anders Wang", "Developer Division"); Console.WriteLine(new EmployeeEqualityComparer().Equals(anders, jeffrey)); //output false Console.WriteLine(new EmployeeEqualityComparer().Equals(anders, steve)); //output true Console.ReadKey(); }
以上代码通过实现IEqualityComparer<T>接口说明了如何判断两个对象相等。
总结
.NET框架提供了IComparable、IComparable<T>、IComparer<T>、IEqualityComparer<T>,这几个接口对于实现排序算法有着直接的作用,在泛型的帮助下,可以编写出通用的排序算法,只需要你根据特定的类型实现以上几个接口中的方法。正是因为接口,使得大家都有了规约,进而使得通用的排序算法实现变得可能。另外在处理和集合相关的类型时,比如字典,哈希表等数据结构时, 当你因为具体的语义覆盖了键类型的Equals方法后,务必必也要覆盖GetHashCode方法。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· 展开说说关于C#中ORM框架的用法!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?