C#笔记25:比较和排序(IComparable和IComparer以及它们的泛型实现)

本文摘要:

1:比较和排序的概念;

2:IComparable和IComparer;

3:IComparable和IComparer的泛型实现IComparable<T>和IComparer<T>;

1:比较和排序的概念

比较:两个实体类之间按>,=,<进行比较。

排序:在集合类中,对集合类中的实体进行排序。排序基于的算法基于实体类提供的比较函数。

基本型别都提供了默认的比较算法,如string提供了按字母进行比较,int提供了按整数大小进行比较。

2:IComparable和IComparer

当我们创建了自己的实体类,如Student,默认想要对其按照年龄进行排序,则需要为实体类实现IComparable接口。

  1. class Student:IComparable
  2. {
  3. public string Name { get; set; }
  4. public int Age { get; set; }
  5.  
  6. #region IComparable Members
  7.  
  8. public int CompareTo(object obj)
  9. {
  10. Student student = obj as Student;
  11. if (Age > student.Age)
  12. {
  13. return ;
  14. }
  15. else if (Age == student.Age)
  16. {
  17. return ;
  18. }
  19. else
  20. {
  21. return -;
  22. }
  23. //return Age.CompareTo(student.Age);
  24. }
  25. #endregion
  26. }
  1. PS:注意上面代码中CompareTo方法有一条注释的代码,其实本函数完全可以使用该注释代码代替,因为利用了整形的默认比较方法。此处未使用本注释代码,是为了更好的说明比较器的工作原理。
  1. 接下来写一个测试用例:
  1. public Form1()
  2. {
  3. InitializeComponent();
  4. studentList = new ArrayList();
  5. studentList.Add(new Student() { Age = , Name = "a1" });
  6. studentList.Add(new Student() { Age = , Name = "g1" });
  7. studentList.Add(new Student() { Age = , Name = "b1" });
  8. studentList.Add(new Student() { Age = , Name = "f1" });
  9. }
  10. ArrayList studentList;
  11. private void button1_Click(object sender, EventArgs e)
  12. {
  13. studentList.Sort();
  14. foreach (Student item in studentList)
  15. {
  16. this.textBox1.Text += item.Name + "----" +item.Age.ToString() + "\r\n" ;
  17. }
  18. }

运行结果:

a1----1
f1----2
b1----4
g1----5

OK,疑问来了。如果不想使用年龄作为比较器了,那怎么办。这个时候IComparer的作用就来了,可使用IComparer来实现一个自定义的比较器。如下:

  1. class SortName: IComparer
  2. {
  3. #region IComparer Members
  4.  
  5. public int Compare(object x, object y)
  6. {
  7. Student s1 = x as Student;
  8. Student s2 = y as Student;
  9. return s1.Name.CompareTo(s2.Name);
  10. }
  11.  
  12. #endregion
  13. }

这个时候,我们在排序的使用为Sort方法提供此比较器:

studentList.Sort(new SortName());

运行的结果是:

a1----1
b1----4
f1----2
g1----5

3:IComparable和IComparer的泛型实现IComparable<T>和IComparer<T>

如果我们稍有经验,我们就会发现上面的代码我们使用了一个已经不建议使用的集合类ArrayList。当泛型出来后,所有非泛型集合类已经建议不尽量使用了。至于原因,从上面的代码中我们也可以看出一点端倪。

注意查看这个Compare函数,如:

  1. public int Compare(object x, object y)
  2. {
  3. Student s1 = x as Student;
  4. Student s2 = y as Student;
  5. return s1.Name.CompareTo(s2.Name);
  6. }

我们发现这个函数进行了装箱和拆箱。而这是会影响性能的。如果我们的集合中有成千上万个复杂的实体对象,则在排序的时候所耗费掉的性能就是客观的。而泛型的出现,就可以避免掉拆箱和装箱。

故上文代码中的ArrayList,应该换成List<T>,对应的,我们就该实现IComparable<T>和IComparer<T>。最终的代码应该像:

  1. public partial class Form1 : Form
  2. {
  3. public Form1()
  4. {
  5. InitializeComponent();
  6. studentList = new List<Student>();
  7. studentList.Add(new Student() { Age = , Name = "a1" });
  8. studentList.Add(new Student() { Age = , Name = "g1" });
  9. studentList.Add(new Student() { Age = , Name = "b1" });
  10. studentList.Add(new Student() { Age = , Name = "f1" });
  11. }
  12. List<Student> studentList;
  13. private void button1_Click(object sender, EventArgs e)
  14. {
  15. studentList.Sort(new SortName());
  16.  
  17. foreach (Student item in studentList)
  18. {
  19.  
  20. this.textBox1.Text += item.Name + "----" +item.Age.ToString() + "\r\n" ;
  21. }
  22. }
  23. }
  24.  
  25. class Student:IComparable<Student>
  26. {
  27. public string Name { get; set; }
  28. public int Age { get; set; }
  29.  
  30. #region IComparable<Student> Members
  31.  
  32. public int CompareTo(Student other)
  33. {
  34. return Age.CompareTo(other.Age);
  35. }
  36.  
  37. #endregion
  38. }
  39.  
  40. class SortName: IComparer<Student>
  41. {
  42. #region IComparer<Student> Members
  43.  
  44. public int Compare(Student x, Student y)
  45. {
  46. return x.Name.CompareTo(y.Name);
  47. }
  48.  
  49. #endregion
  50. }

比较和排序(IComparable和IComparer以及它们的泛型实现)(转)的更多相关文章

  1. 比较和排序(IComparable和IComparer以及它们的泛型实现)

    本文摘要: 1:比较和排序的概念: 2:IComparable和IComparer: 3:IComparable和IComparer的泛型实现IComparable<T>和ICompare ...

  2. 比较和排序 IComparable And IComparer

    1.List<Student>默认排序 为类创建默认排序实现IComparable,此代码的实现为年龄升序 using System; using System.Collections.G ...

  3. C# 比较和排序(IComparable和IComparer以及它们的泛型实现)

    准备工作: 1.创建实体类:ClassInfo,默认想要对其按照班级学生数量进行排序 public class ClassInfo  { /// <summary> /// 班级名称 // ...

  4. 数组自定义排序:IComparable和IComparer接口

    首先先说一下IComparable和IComparer的区别,前者必须在实体类中实现,后者可以单独出现在一个排序类中,即此类只包含一个compare方法. Array类使用快速算法对数组中的元素进行排 ...

  5. c# 实现IComparable、IComparer接口、Comparer类的详解

    在默认情况下,对象的Equals(object o)方法(基类Object提供),是比较两个对象变量是否引用同一对象.我们要必须我自己的对象,必须自己定义对象比较方式.IComparable和ICom ...

  6. C# 常用接口学习 IComparable 和 IComparer

    C# 常用接口学习 IComparable 和 IComparer 作者:乌龙哈里 时间:2015-11-01 平台:Window7 64bit,Visual Studio Community 201 ...

  7. C# 中的IComparable和IComparer

    前言 在开发过程中经常会遇到比较排序的问题,比如说对集合数组的排序等情况,基本类型都提供了默认的比较算法,如string提供了按字母进行排序,而int整数则是根据整数大小进行排序.但是在引用类型中(具 ...

  8. [0] 关于IComparable和IComparer接口和Comparer类

    关于IComparable和IComparer接口 和 Comparer类 IComparable和ICompareframeworkr接口是.net 中比较对象的标准方式,这两个接口之间的区别如下: ...

  9. C#的 IComparable 和 IComparer接口及ComparableTo方法的 区别(非常重要)

    (1)https://blog.csdn.net/ios99999/article/details/77800819 C# IComparable 和 IComparer 区别 (2)https:// ...

随机推荐

  1. mono for android 百度map binding项目(转)

    好丫小子之前发布过百度地图android SDK的mono for android绑定dll,许多朋友看过之后说想理解是怎么绑定的,现我把绑定的代码发出来. 针对2.1.2版本百度地图android ...

  2. nginx安装及其配置详细教程

    1 nginx 介绍 1 什么是nginx Nginx是一款高性能的http 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器. 由俄罗斯的程序设计师Igor Sysoev所开发,官方 ...

  3. python-FTP模块

    #!/user/bin/python #coding=utf-8 import ftplib import os import socket HOST = 'ftp.kernel.org' DIRN ...

  4. 对Tensorflow中tensor的理解

    Tensor即张量,在tensorflow中所有的数据都通过张量流来传输,在看代码的时候,对张量的概念很不解,很容易和矩阵弄混,今天晚上查了点资料,并深入了解了一下,简单总结一下什么是张量的阶,以及张 ...

  5. 打乱数组——shuffle

    在学习vue移动端音乐项目时,看到一个打乱数组函数,感觉很有意思就记录一下(意外发现:slice是个有趣的知识点) 原理:遍历数组,(let i = 0; i < _arr.length; i+ ...

  6. Android四大组件--活动(Activity)

    1. 概念 说明: 1). 创建和销毁 onCreate 和 onDestory 应用场景:当界面销毁的时候存储一些数据,在onCreate创建的时候回显数据: 例如:发短信:写短信写到一半,按hom ...

  7. Redis常用命令整理

    doc 环境下使用命令:       keys 命令         ?    匹配一个字符         *    匹配任意个(包括0个)字符         []    匹配括号间的任一个字符, ...

  8. c#参数修饰符-params

    先来理解一下理论知识 params可以设置使用长度可变的参数. 使用要求: 1.在一个方法声明的参数中,只能有一个params修饰符,且被修饰的参数之后不能有其他参数(这一点就像“可选参数必须在必选参 ...

  9. django中的template部分

    模版部分 取值 {{key}} 语句块 {%for item in data%} {%extends 'base.html'%} 深度变量的查找(万能的句点号) 在到目前为止的例子中,我们通过 con ...

  10. Best MVC Practices 最佳的MVC实践

    Although Model-View-Controller (MVC) is known by nearly every Web developer, how to properly use MVC ...