来源: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>泛型接口的更多相关文章

  1. .NET/C#中对自定义对象集合进行自定义排序的方法

    一个集合可否排序,要看系统知不知道排序的规则,像内建的系统类型,int ,string,short,decimal这些,系统知道怎么排序,而如果一个集合里面放置的是自定义类型,比如自己定义了一个Car ...

  2. 复杂对象List集合的排序

    对于集合的排序,直接的有sort().间接的有借用compareTo.Comparable等,但是对于相对复杂的对象集合,还得自己实现方法来处理. 现在有这样一个思路: 第一步:从需要排序的对象集合中 ...

  3. js对象数组多字段排序

    来源:js对象数组按照多个字段进行排序 一.数组排序 Array.sort()方法可以传入一个函数作为参数,然后依据该函数的逻辑,进行数组的排序. 一般用法:(数组元素从小大进行排序) var a = ...

  4. java实现两个不同list对象合并后并排序

    工作上遇到一个要求两个不同list对象合并后并排序1.问题描述从数据库中查询两张表的当天数据,并对这两张表的数据,进行合并,然后根据时间排序.2.思路从数据库中查询到的数据放到各自list中,先遍历两 ...

  5. 程序员必知的8大排序(三)-------冒泡排序,快速排序(java实现)

    程序员必知的8大排序(一)-------直接插入排序,希尔排序(java实现) 程序员必知的8大排序(二)-------简单选择排序,堆排序(java实现) 程序员必知的8大排序(三)-------冒 ...

  6. java工具类之按对象中某属性排序

    import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang ...

  7. SDUT OJ 数据结构实验之排序三:bucket sort

    数据结构实验之排序三:bucket sort Time Limit: 250 ms Memory Limit: 65536 KiB Submit Statistic Discuss Problem D ...

  8. SDUT 3400 数据结构实验之排序三:bucket sort

    数据结构实验之排序三:bucket sort Time Limit: 150MS Memory Limit: 65536KB Submit Statistic Problem Description ...

  9. iOS--自定义相册---对象数组按照时间戳排序

    将对象按照时间戳排序,这里典型的一个例子是登录账户的排序:本地客户端可能保存了多个账户信息,在登录窗口用户可以选择已经登陆过的账户直接登录,现在的需求是要时刻让最近登陆过的账户排在前面,对于每个账户, ...

随机推荐

  1. <div>里用display:block有用么?

    对所有的块元素都没有意义,块元素的dispaly属性默认值为block,没必要再显式定义--除非你之前对块元素的display属性重新定义过. =========================== ...

  2. pat1011. World Cup Betting (20)

    1011. World Cup Betting (20) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue Wit ...

  3. JS的从理解对象到创建对象

    JavaScript不是一门真正的面向对象语言,因为它连最基本的类的概念都没有,因此它的对象和基于类的语言中的对象也会有所不同.ECMA-262把对象定义为:“无序属性的集合,其属性可以包含基本值.对 ...

  4. 2017 年 9 月 27 日 js(1.两个select 内容互换 2.单选按钮 同意可点击下一步 3. 全选框)

    1.两个select 内容互换 <!DOCTYPE html><html>    <head>        <meta charset="UTF- ...

  5. Juniper 防火墙端口映射设置

    首先我们登陆到juniper防火墙控制界面 默认地址大家都知道(192.168.1.1) 默认用户和密码netsscreen 下面介绍登陆界面: 让我们开始配置吧 依次展开policy → Polic ...

  6. Wpf ListView展示风格

    ListView数据绑定控件,通常是竖列展示,也可以通过改变ListView的布局来改变它的展示方式 如图展示: 主要需用修改的样式如下: <!--GridView Header样式 去除Gri ...

  7. DJango小总结一

    views.py                        def func(request):                # 包含所有的请求数据                ...     ...

  8. 【学习笔记】HTML基础:列表、表格与媒体元素

    一.列表是信息资源的一种展现形式,它可以使信息结构化和条理化,并以列表的样式显示出来,以便浏览者能够快速的获取相应的信息. 1.无需列表 <ul> <li>第一项</li ...

  9. CRM——讲师与学生

    一.课程记录和学习记录 1.初始化 course_record, study_record.2.学习记录3.录入成绩4.显示成绩 ajax 查询 柱状图展示成绩 highcharts 5.上传作业(o ...

  10. jquery获取transform里面的值

    用transform的translateX写了一个侧滑效果,如何获取它改变的值是多少呢? 获取translateX值的方法: $('div').css("transform").r ...