C#泛型集合自定义比较器实现排序

目录

 

需求:根据自定义的类中字段实现自定义的排序规则。

解决方案:

实现:

 方法一:该自定义类实现IComparable接口。

方法二:创建比较器类,该类实现接口IComparer

方法三:实现内置Comparison委托

总结:


需求:根据自定义的类中字段实现自定义的排序规则。

解决方案:

1.public void Sort();
  使用默认比较器对整个 System.Collections.Generic.List`1 中的元素进行排序。这里的默认比较器就是指Comparer<T>.Default。要使用默认比较器来排序,则类必须实现IComparable<T>接口,排序的时候会调用接口的CompareTo方法
2.public void Sort(IComparer<T> comparer);
  使用指定的比较器对整个 System.Collections.Generic.List`1 中的元素进行排序。
3.public void Sort(Comparison<T> comparison);
   使用指定的 System.Comparison`1,对整个 System.Collections.Generic.List`1 中的元素进行排序
   其中:Comparison是.NET内置的一个委托。
  原型为: public delegate int Comparison<in T>(T x, T y);//两个同类型的输入参数,一个整形返回值的签名。
  表示用于比较相同类型的两个对象的方法。使用委托,可以传递一个与委托签名相同的函数,可以使用匿名委托,还可以用Lambda表达式。
4.public void Sort(int index, int count, IComparer<T> comparer);//与方法三大同小异

实现:

 方法一:该自定义类实现IComparable接口。

 class StudentData1:IComparable
    {
        private string name;
        private int age;
        private string gender;
        public string Name { get => name; set => name = value; }
        public int Age { get => age; set => age = value; }
        public string Gender { get => gender; set => gender = value; }

        public StudentData1(int age, string name, string gender)
        {
            this.age = age;
            this.name = name;
            this.gender = gender;
        }

        static void Main(string[] args)
        {

            List<StudentData1> data = new List<StudentData1>();
            data.Add(new StudentData1(28, "貂蝉", "female"));
            data.Add(new StudentData1(37, "关羽", "male"));
            data.Add(new StudentData1(27, "赵云", "male"));
            data.Add(new StudentData1(27, "马超", "male"));
            data.Add(new StudentData1(39, "黄忠", "male"));
            data.Add(new StudentData1(28, "诸葛亮", "male"));
            foreach (var item in data)
            {
                Console.WriteLine(item.Age + item.Name + item.Gender);
            }
            Console.WriteLine("本类实现IComparable接口后");
            data.Sort();
            foreach (var item in data)
            {
                Console.WriteLine(item.Age + item.Name + item.Gender);
            }
            Console.ReadKey();
        }
  //对自定义的StudentData1类实现按照年龄,姓名名称的顺序排序
        public int CompareTo(object obj)
        {
            StudentData1 studentData1 = (StudentData1)obj;
            if (this.Age > studentData1.Age)
            {
                return 1;
            }
            else if (this.Age < studentData1.Age)
            {
                return -1;
            }
            else
            {
                return string.Compare(this.Name, studentData1.Name);
            }
        }
    }

方法二:创建比较器类,该类实现接口IComparer

   //创建比较器类,该类实现接口IComparer,在不修改已有的类,创建自己的比较器类
    class StudentDataCompare : IComparer<StudentData>
    {

        public int Compare(StudentData x, StudentData y)
        {
            StudentData studentDatax = x as StudentData;
            StudentData studentDatay = y as StudentData;
            if (studentDatax.Age > studentDatay.Age)
            {
                return 1;
            }
            else if (studentDatax.Age < studentDatay.Age)
            {
                return -1;

            }
            else
            {
                return (string.Compare(studentDatax.Name, studentDatay.Name));
            }
         
        }


    }
     static void Main(string[] args)
        {
            List<StudentData> data = new List<StudentData>();
            data.Add(new StudentData(28, "貂蝉", "female"));
            data.Add(new StudentData(37, "关羽", "male"));
            data.Add(new StudentData(27, "赵云", "male"));
            data.Add(new StudentData(27, "马超", "male"));
            data.Add(new StudentData(39, "黄忠", "male"));
            data.Add(new StudentData(28, "诸葛亮", "male"));
            //排序前
            foreach (var item in data)
            {
                Console.WriteLine(item.Age + item.Name + item.Gender);

            }
            data.Sort(new StudentDataCompare());
            Console.WriteLine("使用自定义的实现IComparer<StudentData>接口的自定义比较类后");
            foreach (var item in data)
            {
                Console.WriteLine(item.Age + item.Name + item.Gender);
            }
            Console.ReadKey();
        }

方法三:实现内置Comparison委托

   static void Main(string[] args)
        {
            List<StudentDataComparsion> data = new List<StudentDataComparsion>();
            data.Add(new StudentDataComparsion(28, "貂蝉", "female"));
            data.Add(new StudentDataComparsion(37, "关羽", "male"));
            data.Add(new StudentDataComparsion(27, "赵云", "male"));
            data.Add(new StudentDataComparsion(27, "马超", "male"));
            data.Add(new StudentDataComparsion(39, "黄忠", "male"));
            data.Add(new StudentDataComparsion(28, "诸葛亮", "male"));
            //排序前
            foreach (var item in data)
            {
                Console.WriteLine(item.Age + item.Name + item.Gender);

            }
            data.Sort(Compare);//传入符合签名的函数
            

            Console.WriteLine("使用自定义的实现IComparer<StudentData>接口的自定义比较类后");
            foreach (var item in data)
            {
                Console.WriteLine(item.Age + item.Name + item.Gender);
            }
            Console.ReadKey();
        }
        private static int Compare(StudentDataComparsion studentDataComparsion1, StudentDataComparsion studentDataComparsion2)
        {
            if (studentDataComparsion1.Age == studentDataComparsion2.Age)
            {
                return (string.Compare(studentDataComparsion1.Name, studentDataComparsion2.Name));
            }
            else if (studentDataComparsion1.Age > studentDataComparsion2.Age)
            {
                return 1;
            }
            else
            {
                return -1;
            }
        }

总结:

方法一在当前类中进行修改。方法二在不修改已有的类,创建自己的比较器类,比较灵活。其他的比如

利用Lamda表达式,匿名函数这里暂不做介绍。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值