• 比较和排序(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() + "
    "  ;
                }
            }
    

          运行结果:

    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() + "
    "  ;
                }
            }
        }
    
        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(包含链接)。如您有任何疑问或者授权方面的协商,请给我留言。
  • 相关阅读:
    Java SE 疑难点记录
    重写(OverRide)与重载(OverlLoad),以及相对应的多态性
    Static 作用探讨
    Java SE作业:判断一个字符串是否是视频文件
    轨迹压缩之Douglas-Peucker算法之Java实现
    论主动思考与专注力——我的读研感悟
    西安电子科技大学2011级计算机科学与技术专业知识体系结构图
    Hadoop分布式平台概述
    Jest测试框架(未完)
    项目经验总结
  • 原文地址:https://www.cnblogs.com/lsgsanxiao/p/5391695.html
Copyright © 2020-2023  润新知