比较和排序(IComparable和IComparer以及它们的泛型实现)
本文摘要:
1:比较和排序的概念;
2:IComparable和IComparer;
3:IComparable和IComparer的泛型实现IComparable<T>和IComparer<T>;
1:比较和排序的概念
比较:两个实体类之间按>,=,<进行比较。
排序:在集合类中,对集合类中的实体进行排序。排序基于的算法基于实体类提供的比较函数。
基本型别都提供了默认的比较算法,如string提供了按字母进行比较,int提供了按整数大小进行比较。
2:IComparable和IComparer
当我们创建了自己的实体类,如Student,默认想要对其按照年龄进行排序,则需要为实体类实现IComparable接口。
class Student:IComparable
{
public string Name { get; set; }
public int Age { get; set; } #region IComparable Members public int CompareTo(object obj)
{
Student student = obj as Student;
if (Age > student.Age)
{
return 1;
}
else if (Age == student.Age)
{
return 0;
}
else
{
return -1;
}
//return Age.CompareTo(student.Age);
}
#endregion
}
PS:注意上面代码中CompareTo方法有一条注释的代码,其实本函数完全可以使用该注释代码代替,因为利用了整形的默认比较方法。此处未使用本注释代码,是为了更好的说明比较器的工作原理。
接下来写一个测试用例:
public Form1()
{
InitializeComponent();
studentList = new ArrayList();
studentList.Add(new Student() { Age = 1, Name = "a1" });
studentList.Add(new Student() { Age = 5, Name = "g1" });
studentList.Add(new Student() { Age = 4, Name = "b1" });
studentList.Add(new Student() { Age = 2, Name = "f1" });
}
ArrayList studentList;
private void button1_Click(object sender, EventArgs e)
{
studentList.Sort();
foreach (Student item in studentList)
{
this.textBox1.Text += item.Name + "----" +item.Age.ToString() + "\r\n" ;
}
}
运行结果:
a1----1
f1----2
b1----4
g1----5
OK,疑问来了。如果不想使用年龄作为比较器了,那怎么办。这个时候IComparer的作用就来了,可使用IComparer来实现一个自定义的比较器。如下:
class SortName: IComparer
{
#region IComparer Members public int Compare(object x, object y)
{
Student s1 = x as Student;
Student s2 = y as Student;
return s1.Name.CompareTo(s2.Name);
} #endregion
}
这个时候,我们在排序的使用为Sort方法提供此比较器:
studentList.Sort(new SortName());
运行的结果是:
a1----1
b1----4
f1----2
g1----5
3:IComparable和IComparer的泛型实现IComparable<T>和IComparer<T>
如果我们稍有经验,我们就会发现上面的代码我们使用了一个已经不建议使用的集合类ArrayList。当泛型出来后,所有非泛型集合类已经建议不尽量使用了。至于原因,从上面的代码中我们也可以看出一点端倪。
注意查看这个Compare函数,如:
public int Compare(object x, object y)
{
Student s1 = x as Student;
Student s2 = y as Student;
return s1.Name.CompareTo(s2.Name);
}
我们发现这个函数进行了装箱和拆箱。而这是会影响性能的。如果我们的集合中有成千上万个复杂的实体对象,则在排序的时候所耗费掉的性能就是客观的。而泛型的出现,就可以避免掉拆箱和装箱。
故上文代码中的ArrayList,应该换成List<T>,对应的,我们就该实现IComparable<T>和IComparer<T>。最终的代码应该像:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
studentList = new List<Student>();
studentList.Add(new Student() { Age = 1, Name = "a1" });
studentList.Add(new Student() { Age = 5, Name = "g1" });
studentList.Add(new Student() { Age = 4, Name = "b1" });
studentList.Add(new Student() { Age = 2, Name = "f1" });
}
List<Student> studentList;
private void button1_Click(object sender, EventArgs e)
{
studentList.Sort(new SortName()); foreach (Student item in studentList)
{ this.textBox1.Text += item.Name + "----" +item.Age.ToString() + "\r\n" ;
}
}
} class Student:IComparable<Student>
{
public string Name { get; set; }
public int Age { get; set; } #region IComparable<Student> Members public int CompareTo(Student other)
{
return Age.CompareTo(other.Age);
} #endregion
} class SortName: IComparer<Student>
{
#region IComparer<Student> Members public int Compare(Student x, Student y)
{
return x.Name.CompareTo(y.Name);
} #endregion
}
转自:本文基于Creative Commons Attribution 2.5 China Mainland License发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名http://www.cnblogs.com/luminji(包含链接)。如您有任何疑问或者授权方面的协商,请给我留言。
比较和排序(IComparable和IComparer以及它们的泛型实现)的更多相关文章
- 比较和排序(IComparable和IComparer以及它们的泛型实现)(转)
C#笔记25:比较和排序(IComparable和IComparer以及它们的泛型实现) 本文摘要: 1:比较和排序的概念: 2:IComparable和IComparer: 3:IComparabl ...
- 比较和排序 IComparable And IComparer
1.List<Student>默认排序 为类创建默认排序实现IComparable,此代码的实现为年龄升序 using System; using System.Collections.G ...
- C# 比较和排序(IComparable和IComparer以及它们的泛型实现)
准备工作: 1.创建实体类:ClassInfo,默认想要对其按照班级学生数量进行排序 public class ClassInfo { /// <summary> /// 班级名称 // ...
- 数组自定义排序:IComparable和IComparer接口
首先先说一下IComparable和IComparer的区别,前者必须在实体类中实现,后者可以单独出现在一个排序类中,即此类只包含一个compare方法. Array类使用快速算法对数组中的元素进行排 ...
- c# 实现IComparable、IComparer接口、Comparer类的详解
在默认情况下,对象的Equals(object o)方法(基类Object提供),是比较两个对象变量是否引用同一对象.我们要必须我自己的对象,必须自己定义对象比较方式.IComparable和ICom ...
- C# 常用接口学习 IComparable 和 IComparer
C# 常用接口学习 IComparable 和 IComparer 作者:乌龙哈里 时间:2015-11-01 平台:Window7 64bit,Visual Studio Community 201 ...
- C# 中的IComparable和IComparer
前言 在开发过程中经常会遇到比较排序的问题,比如说对集合数组的排序等情况,基本类型都提供了默认的比较算法,如string提供了按字母进行排序,而int整数则是根据整数大小进行排序.但是在引用类型中(具 ...
- [0] 关于IComparable和IComparer接口和Comparer类
关于IComparable和IComparer接口 和 Comparer类 IComparable和ICompareframeworkr接口是.net 中比较对象的标准方式,这两个接口之间的区别如下: ...
- C#的 IComparable 和 IComparer接口及ComparableTo方法的 区别(非常重要)
(1)https://blog.csdn.net/ios99999/article/details/77800819 C# IComparable 和 IComparer 区别 (2)https:// ...
随机推荐
- js中apply方法的使用
js中apply方法的使用 1.对象的继承,一般的做法是复制:Object.extend prototype.js的实现方式是: Object.extend = function(destinat ...
- JS判断客户端是手机还是PC的2个代码(转)
转载自:http://www.jb51.net/article/48939.htm Javascript 判断客户端是否为 PC 还是手持设备,有时候项目中需要用到,很方便的检测,源生的哦,方法一共有 ...
- 【linux】ps
来源:http://blog.chinaunix.net/uid-25681671-id-3201927.html Linux下PS命令详解 要对系统中进程进行监测控制,查看状态,内存,CPU的使用情 ...
- xcode7 免费真机调试
原文链接:http://www.cnblogs.com/tandaxia/p/4839997.html 刚新安装了Xcode7 Version 7.1 beta , 据说这个版本可以免费真机调试,于是 ...
- js中masonry与infinitescroll结合 形成瀑布流
后台:(有点问题 page应该从1开始 而不是从0开始) public function actionExperts() { $top=5; $page=em ...
- WAMP2.5 Forbidden
Forbidden You don't have permission to access /DuoLamPHP/index.php on this server. Apache/2.4.9 (Win ...
- mysql 查看存储引擎的状态 show engine innodb status 详解
首先,让我们来了解一下 SHOW INNODB STATUS 输出的基础,它打印了很多关于 InnoDB 内部性能相关的计数器.统计.事务处理信息等.在 MySQL 5 中,InnoDB 的性能统计结 ...
- strlen与sizeof
strlen计算不包括终止符null字节的字符串长度,而sizeof则计算包括终止null字节的长度.另一个差别,strlen需要一次函数调用,而sizeof在编译时计算缓冲区长度.
- 使用xib需要记得的小问题
1. 图片 加载 图片上的label 不显示, 最后是因为xib 里位置动了 图片跑到最上层盖住了labe 2. 加载xib 有时候会崩 或加载不出来 先查看xib 是否有多余控件 3. 查看关联 ...
- 关于ActionContext.getContext()的用法心得
转: 为了避免与Servlet API耦合在一起,方便Action类做单元测试,Struts 2对HttpServletRequest.HttpSession和ServletContext进行了封装, ...