比较和排序(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(包含链接)。如您有任何疑问或者授权方面的协商,请给我留言。
时间: 2025-01-05 16:17:22

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

比较和排序 IComparable And IComparer

1.List<Student>默认排序 为类创建默认排序实现IComparable,此代码的实现为年龄升序 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace IComparable_And_IComparer.Model { /// <summary> /// 学生类 /// <

比较和排序:IComparable和IComparer

创建实体类,如Person,默认按照年龄进行排序,则需要为实体类实现IComparable接口. class Person : IComparable { public string Name { get; set; } public int Age { get; set; } public override string ToString() { return string.Format("Name : {0} ; Age : {1} .", this.Name, this.Age)

C# 中的IComparable和IComparer

前言 在开发过程中经常会遇到比较排序的问题,比如说对集合数组的排序等情况,基本类型都提供了默认的比较算法,如string提供了按字母进行排序,而int整数则是根据整数大小进行排序.但是在引用类型中(具有多个字段),那么这个排序当然也是取决于我们特定的值. IComparable接口 该接口由其值可以排序或排序的类型实现,并提供强类型的比较方法以对泛型集合对象的成员进行排序,例如数字可以大于第二个数字,一个字符串可以在另一个字符串之前以字母顺序出现.他要求实现类型定义的一个方法,CompareTo

对象的比较与排序:IComparable和IComparer接口

IComparable和ICompare 接口是.net framework 中比较对象的标准方式,这两个接口提供一个返回值类似(大于0 等于0 小于0)的比较方法,二者区别如下: 1. IComparable 在要比较的对象的类中实现,可以比较该对象和另一个对象. 2. IComparer 在一个单独的类中实现,可以比较任意两个对象. 先看 IComparable 这个接口方法是 int CompareTo(object obj); 方法只有一个参数,我们知道比较至少要有两个对象,所以这个方法

C# 常用接口学习 IComparable 和 IComparer

作者:乌龙哈里 时间:2015-11-01 平台:Window7 64bit,Visual Studio Community 2015 参考: Microsoft Refernce Souce MSDN 章节: 接口 IConmparable 实现 接口 IComparable<T> 实现 接口 IComparer<T> 实现 正文: 一.接口 IConmparable 的实现 class Fruit {     public string Name;     public int

C# 用实例来理解IComparable和IComparer

通过Array的Sort方法来理解的 Sort方法要 通过对象去继承IComparable接口来实现排序(当然也有其它办法),我想入门这可能就是对这句话有点不理解,在下面会有注释 using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Collections; namespace ConsoleApplication1{ /// <summary> /// 设置

IComparable和IComparer接口

C#中,自定义类型,支持比较和排序,需要实现IComparable接口.IComparable接口存在一个名为CompareTo()的方法,接收类型为object的参数表示被比较对象,返回整型值:1表示当前对象大于被比较对象,0表示两者相等,-1表示当前对象小于被比较对象. public int CompareTo(object o) {} 若想以更加灵活的方式对自定义类进行比较,可以声明一个继承自IComparer接口的比较器,实现接口方法Comprae(),接收2个object类型参数作为比

IComparable和IComparer

using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace no._1 { class Program { static void Main(string[] args) { ArrayList arr1 = new ArrayList() { new P

IComparable和IComparer接口的简析

默认情况下,对象的Equals(object o)方法是比较两个对象是否引用同一个对象.如果我们有自己的对象,就要自己定义对象比较方式: 1.IComparable在要比较的对象(类的实例化就是对象)类中实现,可以比较该对象和另一个对象. 2.IComparer在一个单独的类中实现,可以任意比较两个对象. 通俗的讲,IComparable是能够比较,具备比较的能力.比如说某个人具备编程的能力,如果需要对编程能力的高低进行比较的话,就必须在自己的类中去实现怎么具体的方法.IComparer是比较者