对象的比较与排序(三):实现IComparable<T>和IComparer<T>泛型接口
来源:http://www.cnblogs.com/eagle1986/archive/2011/12/06/2278531.html
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
{
public static IComparer Default = new PersonComparerName();
#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(SortName.Default);
运行的结果是:
a1----1
b1----4
f1----2
g1----5
上一篇日记已经说过,
一般情况下,我们使用 IComparable 给出类的默认比较代码,使用其他类给出非默认的比较代码。
上面的示例,其中,我们在Student给出了默认的比较代码(实现了IComparable),所以我们可以通过 .Sort()来进行排序。
同时我们也可以给出非默认的比较代码,比如示例中的SortName (要求实现 IComparer接口),所以我们可以通过 .Sort(SortName.Default)来进行排序。
只要是实现是 IComparer接口就可以作为比较器参数丢给Sort().
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
}
对象的比较与排序(三):实现IComparable<T>和IComparer<T>泛型接口的更多相关文章
- .NET/C#中对自定义对象集合进行自定义排序的方法
一个集合可否排序,要看系统知不知道排序的规则,像内建的系统类型,int ,string,short,decimal这些,系统知道怎么排序,而如果一个集合里面放置的是自定义类型,比如自己定义了一个Car ...
- 复杂对象List集合的排序
对于集合的排序,直接的有sort().间接的有借用compareTo.Comparable等,但是对于相对复杂的对象集合,还得自己实现方法来处理. 现在有这样一个思路: 第一步:从需要排序的对象集合中 ...
- js对象数组多字段排序
来源:js对象数组按照多个字段进行排序 一.数组排序 Array.sort()方法可以传入一个函数作为参数,然后依据该函数的逻辑,进行数组的排序. 一般用法:(数组元素从小大进行排序) var a = ...
- java实现两个不同list对象合并后并排序
工作上遇到一个要求两个不同list对象合并后并排序1.问题描述从数据库中查询两张表的当天数据,并对这两张表的数据,进行合并,然后根据时间排序.2.思路从数据库中查询到的数据放到各自list中,先遍历两 ...
- 程序员必知的8大排序(三)-------冒泡排序,快速排序(java实现)
程序员必知的8大排序(一)-------直接插入排序,希尔排序(java实现) 程序员必知的8大排序(二)-------简单选择排序,堆排序(java实现) 程序员必知的8大排序(三)-------冒 ...
- java工具类之按对象中某属性排序
import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang ...
- SDUT OJ 数据结构实验之排序三:bucket sort
数据结构实验之排序三:bucket sort Time Limit: 250 ms Memory Limit: 65536 KiB Submit Statistic Discuss Problem D ...
- SDUT 3400 数据结构实验之排序三:bucket sort
数据结构实验之排序三:bucket sort Time Limit: 150MS Memory Limit: 65536KB Submit Statistic Problem Description ...
- iOS--自定义相册---对象数组按照时间戳排序
将对象按照时间戳排序,这里典型的一个例子是登录账户的排序:本地客户端可能保存了多个账户信息,在登录窗口用户可以选择已经登陆过的账户直接登录,现在的需求是要时刻让最近登陆过的账户排在前面,对于每个账户, ...
随机推荐
- FZU 2207 ——以撒的结合——————【LCA + 记录祖先】
Problem 2207 以撒的结合 Accept: 47 Submit: 161Time Limit: 1000 mSec Memory Limit : 32768 KB Proble ...
- git/github 代码托管图文教程
现在都流行将代码托管到github,使用版本控制工具git,现在让我们开始一步一步的将我们本地的代码托管到github上去吧 一. git的使用 1.下载git工具 2.下载好后安装时候注意要使用vi ...
- js 获取 Url.Action 设置area
var url = '@Url.Action("UserEdit","User",new { Area = "Setup", id = 1} ...
- JavaScript获取url参数
声明:以下内容转自网络 方法一 String.prototype.getUrlString = function(name) { var reg = new RegExp("(^|& ...
- HDU 5007 字符串匹配
http://acm.hust.edu.cn/vjudge/contest/122814#problem/A 匹配到字符串就输出,水题,主要是substr的运用 #include <iostre ...
- 【代码笔记】Java基础:Java的方法和类
面向过程与面向对象都是我们编程中,编写程序的一种思维方式.例如:公司打扫卫生(擦玻璃.扫地.拖地.倒垃圾等), 按照面向过程的程序设计方式会思考“打扫卫生我该怎么做,然后一件件的完成”,最后把公司卫生 ...
- Python基础 数据类型 (字符串、列表、字典、元组、集合、堆、栈、树)
数据类型有整型.布尔.字符串.列表.字典.元组.集合.堆.栈和树. 1.整型: 整型就是数字 数字表示 python2 64位机器,范围-2^63~2^63-1 超出上述范围,python自动转化为l ...
- 软件项目技术点(2)——Canvas之获取Canvas当前坐标系矩阵
AxeSlide软件项目梳理 canvas绘图系列知识点整理 前言 在我的另一篇博文 Canvas坐标系转换 中,我们知道了所有的平移缩放旋转操作都会影响到画布坐标系.那在我们对画布进行了一系列操 ...
- mui 的注意事项点
1.mui的subpage在微信浏览器中不能正常工作. 2.MUI支持json格式解析: 调用JSON.parse(data)或者JSON.stringify(data); 3.
- php基础--取默认值以及类的继承
(1)对于php的默认值的使用和C++有点类似,都是在函数的输入中填写默认值,以下是php方法中对于默认值的应用: <?phpfunction makecoffee($types = array ...