zoukankan      html  css  js  c++  java
  • List集合操作二:排序

    本文继续讲解List<T>之排序操作,C#范型List类的Sort方法有四种形式,分别是:

    1、不带有任何参数的Sort方法----Sort();
    2、带有比较器参数的Sort方法 ----Sort(IComparer<T>)
    3、带有比较代理方法参数的Sort方法----Sort(Comparison<(Of <(T>)>))
    4、带有比较起参数,可以指定排序范围的Sort方法----Sort(Int32, Int32 IComparer(T))

    首先对IComparable.CompareTo 方法进行一下介绍:
    MSDN解释:将当前实例与同一类型的另一个对象进行比较,并返回一个整数,该整数指示当前实例在排序顺序中的位置是位于另一个对象之前、之后还是与其位置相同。
    原型:int CompareTo (Object obj)
    参数 obj:与此实例进行比较的对象。 
    返回值:一个 32 位有符号整数,指示要比较的对象的相对顺序。
    返回值的含义如下:
    小于0 此实例小于 obj;位置在obj之前。
    等于0 此实例等于 obj;位置在obj相同。
    大于0 此实例大于 obj;位置在obj之后。

    下面我们通过一个控制台实例来分别介绍这四种方法:

    第一种方法元素继承IComparable:
    * 使用这种方法不是对List中的任何元素对象都可以进行排序
    * List中的元素对象必须继承IComparable接口并且要实现IComparable接口中的CompareTo()方法
    * 在CompareTo()方法中要自己实现对象的比较规则

    我们还沿用第一篇的实体类Player 并使其继承IComparable接口 

    using System;
    
    namespace ListDemo2
    {
        public class Player : IComparable<Player>
        {
            public Player(int id, string name, string team)
            {
                this.Id = id;
                this.Name = name;
                this.Team = team;
            }
            public int Id { get; set; }
    
            public string Name { get; set; }
    
            public string Team { get; set; }
    
            #region IComparable<Model> 成员
            /// <summary>
            /// 实现的IComparable接口,用于进行比较。因为排序是建立在比较的基础之上的。
            /// </summary>
            /// <param name="otherP">另外一个Player</param>
            /// <returns>
            ///  小于0 此实例按排序顺序在 otherP 前面
            ///  等于0 此实例与otherP 在排序顺序中出现的位置相同
            ///  大于0 此实例按排序顺序在 otherP 后面
            /// </returns>
            public int CompareTo(Player otherP)
            {
                //只要调换位置就可以调整排序的方式
                //return this.Id.CompareTo(otherP.Id); //正序
                return otherP.Id.CompareTo(this.Id);   //倒序
    
            }
            #endregion
        }
    }

     定义一个集合类PlayerList

    using System.Collections.Generic;
    
    namespace ListDemo2
    {
        public class PlayerList : List<Player>
        {
            public PlayerList()
            {
                this.Add(new Player(1, "科比-布莱恩特", "湖人队"));
                this.Add(new Player(2, "保罗-加索尔", "湖人队"));
                this.Add(new Player(3, "拉玛尔-奥多姆", "湖人队"));
                this.Add(new Player(4, "德克-诺维茨基", "小牛队"));
                this.Add(new Player(5, "杰森-特里", "小牛队"));
                this.Add(new Player(6, "肖恩-马里昂", "小牛队"));
                this.Add(new Player(7, "凯文-加内特", "凯尔特人队"));
            }
        }
    }

     Main函数代码:

    using System;
    using System.Collections.Generic;
    
    namespace ListDemo2
    {
        class Program
        {
            static void Main(string[] args)
            {
                //1、不带有任何参数的Sort方法
                PlayerList players = new PlayerList();
                Action<Player> listSort = delegate(Player p)
                {
                    Console.WriteLine(string.Format("队员Id={0} | 队员名称={1} | 所属球队={2} ", p.Id, p.Name, p.Team));
                };
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("第一种不带有任何参数的Sort方法");
                Console.WriteLine("实现元素继承ICompare实现_队员ID从大到小排列:");
                Console.ForegroundColor = ConsoleColor.Yellow;
                players.Sort();
                players.ForEach(listSort);
                Console.ReadKey();
            }
        }
    }

    执行结果如下图:

    第二种带有比较器参数的Sort方法
    * List中的元素对象不需要继承IComparable接口
    * 但需要额外创建一个对象的比较器

    我们重新定义个Student  实体类:

    namespace ListDemo2
    {
        public class Student
        {
            public Student(int id, string name, float score)
            {
                this.Id = id;
                this.Name = name;
                this.Score = score;
            }
            public int Id { get; set; }
            public string Name { get; set; }
            public float Score { get; set; }
        }

    再定义个StudentList集合类:

    using System.Collections.Generic;
    
    namespace ListDemo2
    {
        public class StudentList : List<Student>
        {
            public StudentList()
            {
                this.Add(new Student(1, "小明", 88.5f));
                this.Add(new Student(2, "小红", 90));
                this.Add(new Student(3, "小兰", 93));
                this.Add(new Student(4, "小花", 72.5f));
                this.Add(new Student(5, "小猫", 88));
                this.Add(new Student(6, "小狗", 63));
            }
        }
    }

     我们定义一个StudentCompare类继承 IComparer接口:

    using System;
    using System.Collections.Generic;
    
    namespace ListDemo2
    {
        public class StudentCompare : IComparer<Student>
        {
            //比较器的枚举,可以按照Id 和 Score 进行排序
            public enum CompareType { Id, Score }
    
            private CompareType compareType;
    
            public StudentCompare(CompareType compareType)
            {
                this.compareType = compareType;
            }
    
            public int Compare(Student x, Student y)
            {
                if ((x == null) || (y == null))
                    return -1;
                switch (compareType)
                {
                    case CompareType.Id:
                        return x.Id.CompareTo(y.Id);
                    //成绩从大到小排列
                    case CompareType.Score:
                        return y.Score.CompareTo(x.Score);
                    default:
                        return -1;
                }
            }
        }
    }

     Main函数代码: 

    using System;
    using System.Collections.Generic;
    
    namespace ListDemo2
    {
        class Program
        {
            static void Main(string[] args)
            {           
                //2、带有比较器参数的Sort方法 ---Sort(IComparer<T>)            
                StudentList students1 = new StudentList();
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("第二种带有比较器参数的Sort方法");
                Console.WriteLine("实现_学生成绩从大到小排列:");
                Console.ForegroundColor = ConsoleColor.Yellow;
                students1.Sort(new StudentCompare(StudentCompare.CompareType.Score));
                students1.ForEach(s => Console.WriteLine(string.Format("Id={0} | 姓名={1} | 成绩={2} ", s.Id, s.Name, s.Score)));
                Console.ReadKey();
            }
        }
    }

    执行结果如下图:

     第三种方法需要编写一个对象排序比较的方法
    * 对List中的元素对象没有特殊的要求
    * 但在比较方法中需要实现对象比较规则
    * 这个方法实现后,就可以把这方名字作为参数委托给List的Sort方法
    * Sort方法在排序时会执行这个方法对List中的对象进行比较

    我们写个为学生成绩从小到大排序的比较方法:

    private static int SortStudentCompare(Student stu1, Student stu2)
    {
          return stu1.Score.CompareTo(stu2.Score);
    }

     Main 函数代码: 

    using System;
    using System.Collections.Generic;
    
    namespace ListDemo2
    {
        class Program
        {
            static void Main(string[] args)
            {            
                //3、带有比较代理方法参数的Sort方法
                StudentList student2 = new StudentList();
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("带有比较代理方法参数的Sort方法");
                Console.WriteLine("实现_学生成绩从小到大排列:");
                Console.ForegroundColor = ConsoleColor.Yellow;
                student2.Sort(SortStudentCompare);
                student2.ForEach(s => Console.WriteLine(string.Format("Id={0} | 姓名={1} | 成绩={2} ", s.Id, s.Name, s.Score)));
                Console.ReadKey();
            }
        }
    }

     执行结果如图: 

    第四种方法其实是一种扩展,可以对List内部分数据进行排序

    比如我们可以为StudentList的前三名学生的成绩进行从大到小的排序:

    using System;
    using System.Collections.Generic;
    
    namespace ListDemo2
    {
        class Program
        {
            static void Main(string[] args)
            {
                //4、带有比较起参数,可以指定排序范围的Sort方法
                StudentList student3 = new StudentList();
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("带有比较起参数,可以指定排序范围的Sort方法");
                Console.WriteLine("实现_前3名学生成绩从大到小排列:");
                Console.ForegroundColor = ConsoleColor.Yellow;
                student3.Sort(0, 3, new StudentCompare(StudentCompare.CompareType.Score));
                student3.ForEach(s => Console.WriteLine(string.Format("Id={0} | 姓名={1} | 成绩={2} ", s.Id, s.Name, s.Score)));
                Console.ReadKey();
            }
        }
    }

     执行结果如下图: 

    -=源码下载=-

  • 相关阅读:
    zookeeperclient代码解读
    封装scrollView 循环滚动,tableViewCell(连载) mvc
    PHP经典项目案例-(一)博客管理系统5
    Android插件化(三)载入插件apk中的Resource资源
    比树莓派配置好接地气的香蕉派上手初体验
    HDU Group
    JVM 类的卸载
    JVM 自定义类加载器
    JVM 初始化阶段例子
    JVM 初始化阶段例子 final常量
  • 原文地址:https://www.cnblogs.com/lxblog/p/2652859.html
Copyright © 2011-2022 走看看