前言

在开发过程中经常会遇到比较排序的问题,比如说对集合数组的排序等情况,基本类型都提供了默认的比较算法,如string提供了按字母进行排序,而int整数则是根据整数大小进行排序.但是在引用类型中(具有多个字段),那么这个排序当然也是取决于我们特定的值。

IComparable接口

该接口由其值可以排序或排序的类型实现,并提供强类型的比较方法以对泛型集合对象的成员进行排序,例如数字可以大于第二个数字,一个字符串可以在另一个字符串之前以字母顺序出现。他要求实现类型定义的一个方法,CompareTo(T)该方法指示当前实现在排序顺序中的位置是在同一个类型和第二个对象之前、之后还是与其相同。通常,不会直接从开发人员代码中调用方法。相反他由List.Sort()和Add等方法自动调用。

通常,提供Icomparable实现的类型还IEquatable实现接口。IEquatable接口Equals定义方法,该方法确定实现类型的实例的相等性。

CompareTo(T)方法的实现必须Int32返回具有以下三个值之一的,如下表所示。

含义
小于零 此对象在排序顺序中位于CompareTo方法所指定的对象之前。
此当前实例在排序顺序中与CompareTo方法参数指定的对象出现在同一位置。
大于零 此当前实例位于排序顺序中由CompareTo方法自变量指定的对象之后。

示例:

    class Student : IComparable
{
public string Name { get; set; } public int Age { get; set; }
public int CompareTo(object obj)
{
if (!(obj is Student))
{
throw new ArgumentException("Compared Object is not of student");
}
Student student = obj as Student;
return Age.CompareTo(student.Age);
}
}

Ps:我们根据通过Age(int)来进行我们的排序

执行测试


class Program
{
static void Main(string[] args)
{
ArrayList studentList = new ArrayList {
new Student{Name="a",Age=9 },
new Student{Name="a3",Age=7 },
new Student{Name="a1",Age=6 },
new Student{Name="a2",Age=10 },
};
studentList.Sort();
StudentComparable(studentList); Console.ReadLine();
} private static void StudentComparable(ArrayList studentList)
{
foreach (Student item in studentList)
{
Console.WriteLine("Name:{0},Age:{1}", item.Name, item.Age);
}
}
}

输出如下

IComparer接口

IComparable 接口的CompareTo方法一次只能对一个字段进行排序,因此无法对不同的属性进行排序。IComparer接口提供了Compare方法,该方法比较两个对象并返回一个值,该值指示一个对象小于,等于或大于另一个对象。实现IComparer接口的类必须提供比较两个对象的Compare方法。例如,您可以创建一个StudentComparer类,该类实现IComparer,并具有一个Compare方法,该方法按Name比较Student对象。然后,您可以将StudentComparer对象传递给Array.Sort方法,它可以使用该对象对Student对象的数组进行排序。

示例


class StudentComparer : IComparer
{ public int Compare(object x, object y)
{
Student x1 = x as Student;
Student y1 = y as Student;
return x1.Name.CompareTo(y1.Name);
}
}

Ps:我们根据Name(string)进行排序

执行测试


class Program
{
static void Main(string[] args)
{
ArrayList studentList = new ArrayList {
new Student{Name="a",Age=9 },
new Student{Name="a3",Age=7 },
new Student{Name="a1",Age=6 },
new Student{Name="a2",Age=10 },
};
studentList.Sort(new StudentComparer());
StudentComparable(studentList); Console.ReadLine();
} private static void StudentComparable(ArrayList studentList)
{
foreach (Student item in studentList)
{
Console.WriteLine("Name:{0},Age:{1}", item.Name, item.Age);
}
}
}

输出结果如下

IComparable和IComparer

上述示例中我们将对象进行了多次的装箱和拆箱,那么此时我们可以将方法改为泛型的,泛型的出现也让我们避免了装箱和拆箱的资源浪费.

最终我们实现的代码片段如下:

IComparable


class Student : IComparable<Student>
{
public string Name { get; set; } public int Age { get; set; } public int CompareTo([AllowNull] Student other)
{
return Age.CompareTo(other.Age);
}
}

IComparer


class StudentComparer : IComparer<Student>
{ public int Compare([AllowNull] Student x, [AllowNull] Student y)
{
return x.Name.CompareTo(y.Name); }
}

总结

参考:https://docs.microsoft.com/en-us/dotnet/api/system.icomparable-1?view=netframework-4.8

示例:https://github.com/hueifeng/BlogSample/tree/master/src/CompareDemo

最新文章

  1. Twentydaysgone
  2. mysql5.6新特性总结
  3. javascript标识符
  4. Centos7安装Oracle12c
  5. 标准差(standard deviation)和标准误差(standard error)你能解释清楚吗?
  6. Weex 标签控件
  7. forever 使用
  8. centos上的grub文件修改
  9. iOS 滚动视图的复用问题解决方案
  10. Navicat 连接Oracle时提示oracle library is not loaded的问题解决
  11. 【Linux高级驱动】网卡驱动分析
  12. 自定义bootbox:dialog方法
  13. 生成Markdown目录 字符串解析 MD
  14. Python学习之路 (五)爬虫(四)正则表示式爬去名言网
  15. htm5移动端开发 和 pc端开发
  16. Round 1 Over
  17. java 根据二叉树前序 ,中序求后续
  18. git 码云 使用记录
  19. git&#160;&quot;Could&#160;not&#160;read&#160;from&#160;remote&#160;repository.Please&#160;make&amp;n
  20. jquery控制滚动条

热门文章

  1. PostgreSQL重新读取pg_hba.conf文件
  2. vue页面内监听路由变化
  3. CTR+A组合键 以及终止按键事件传递
  4. python print函数
  5. 洛谷P1510 精卫填海
  6. @codeforces - 1187F@ Expected Square Beauty
  7. NSOperation 详解
  8. 【BestCoder Round #93 1002】MG loves apple
  9. canvas实现碰壁反弹(单个小方块)
  10. NLP进阶之(七)膨胀卷积神经网络