C#List集合实现对对象自定义排序

只谈情不闲聊 提交于 2020-04-07 21:42:43

List排序

List集合对数字或者字母排序可能并不难,不够要是对象排序,就要考虑用对象的哪个字段进行排序。list提供了一个Sort()方法,List已经可以对内置类型(比如:int、double、string)排序,通过对接口的实现也可以定制自己的类排序。可以通过IComparable<T>接口或者IComparer<T>接口实现。

  • 通过IComparer<T>接口实现扑克牌先按排面数字从小到大排序,如果数字相同则按花色枚举值排序

    需要自己构建一个单独的类来帮助List对他的成员排序。创建一个类实现IComparer<T>接口的Compare()方法。它取两个对象参数x,y,并返回一个int类型的值。如果要比较的值x小于y可以返回一个负值,反之返回一个正值,相等返回零。当然你也可以改变返回值来实现升序和降序排列。

    ListCompare.cs

        class ListCompare
        {
            //随机函数
            static Random random = new Random();
            //初始化列表
            public  List<card> cards = new List<card>()
            {
                new card{CardNumber=random.Next(0,14),Cardkind=(Kind)random.Next(0,4)},
                new card{CardNumber=random.Next(0,14),Cardkind=(Kind)random.Next(0,4)},
                new card{CardNumber=random.Next(0,14),Cardkind=(Kind)random.Next(0,4)},
                new card{CardNumber=random.Next(0,14),Cardkind=(Kind)random.Next(0,4)},
                new card{CardNumber=random.Next(0,14),Cardkind=(Kind)random.Next(0,4)},
                new card{CardNumber=random.Next(0,14),Cardkind=(Kind)random.Next(0,4)},
                new card{CardNumber=random.Next(0,14),Cardkind=(Kind)random.Next(0,4)},
                new card{CardNumber=random.Next(0,14),Cardkind=(Kind)random.Next(0,4)},
                new card{CardNumber=random.Next(0,14),Cardkind=(Kind)random.Next(0,4)},
                new card{CardNumber=random.Next(0,14),Cardkind=(Kind)random.Next(0,4)},
            };
            //打印列表
            public void OutputCards(List<card> cards)
            {
                Console.WriteLine("一共{0}张扑克牌,下面为输出结果",cards.Count);
                foreach (card c in cards)
                {
                    Console.WriteLine(c.Cardkind + "\t" + c.CardNumber);
    
                }
            }
        }
        //枚举类型
        enum Kind { 黑桃, 方块, 红桃, 梅花 };//声明扑克四种枚举类型,枚举类型的从小到大顺序
    
        //扑克牌对象
        class card
        {
            public int CardNumber;//数字
            public Kind Cardkind;//花色
        }
    
        //自定义排序类
        class CardCompare : IComparer<card>
        {
            //实现的是降序排列,你也可以改变返回值实现升序排列
            public int Compare(card x, card y)
            {
                if (x.CardNumber > y.CardNumber)
                {
                    return 1;
                }else if(x.CardNumber < y.CardNumber)
                {
                    return -1;
                }
                else//如果数字相同,则比较枚举值,枚举类型都对应一个数值默认从0开始。
                {
                    if (x.Cardkind > y.Cardkind)
                    {
                        return 1;
                    }else if(x.Cardkind < y.Cardkind)
                    {
                        return -1;
                    }
                    else
                    {
                        return 0;//排面花色都相等
                    }
                }
            }
        }
    

    StartClass.cs

    class StarClass
        {
            public static void Main(string[] args)
            {
                ListCompare lc = new ListCompare();
                CardCompare cc = new CardCompare(); //必须要创建比较对象类的实例
                Console.WriteLine("排序前===========");
                lc.OutputCards(lc.cards);//打印列表
                lc.cards.Sort(cc);//比较对象类的实例传入Sort中
                Console.WriteLine("排序后===========");
                lc.OutputCards(lc.cards);//打印列表
                Console.ReadKey();
            }
        }
    

    输出结果

在这里插入图片描述

  • 通过IComparable<T>接口实现扑克牌先按排面数字从小到大排序,如果数字相同则按花色枚举值排序

    修改card类,让card类实现IComparable<T>接口,IComparable<T>接口里面只有一个CompareTo()方法

    取一个对象作为参数,如果要要比较的对象,在有序列表中应当出现在这个对象(自己)的后面,CompareTo()就返回一个正数。

    ListCompare.cs

    class ListCompare
        {
            //随机函数
            static Random random = new Random();
            //初始化列表
            public  List<card> cards = new List<card>()
            {
                new card{CardNumber=random.Next(0,14),Cardkind=(Kind)random.Next(0,4)},
                new card{CardNumber=random.Next(0,14),Cardkind=(Kind)random.Next(0,4)},
                new card{CardNumber=random.Next(0,14),Cardkind=(Kind)random.Next(0,4)},
                new card{CardNumber=random.Next(0,14),Cardkind=(Kind)random.Next(0,4)},
                new card{CardNumber=random.Next(0,14),Cardkind=(Kind)random.Next(0,4)},
                new card{CardNumber=random.Next(0,14),Cardkind=(Kind)random.Next(0,4)},
                new card{CardNumber=random.Next(0,14),Cardkind=(Kind)random.Next(0,4)},
                new card{CardNumber=random.Next(0,14),Cardkind=(Kind)random.Next(0,4)},
                new card{CardNumber=random.Next(0,14),Cardkind=(Kind)random.Next(0,4)},
                new card{CardNumber=random.Next(0,14),Cardkind=(Kind)random.Next(0,4)},
            };
            //打印列表
            public void OutputCards(List<card> cards)
            {
                Console.WriteLine("一共{0}张扑克牌,下面为输出结果",cards.Count);
                foreach (card c in cards)
                {
                    Console.WriteLine(c.Cardkind + "\t" + c.CardNumber);
    
                }
            }
        }
        //枚举类型
        enum Kind { 黑桃, 方块, 红桃, 梅花 };//声明扑克四种枚举类型,枚举类型的从小到大顺序
    
        //扑克牌对象
        class card:IComparable<card>
        {
            public int CardNumber;//数字
            public Kind Cardkind;//花色
    
            public int CompareTo(card other)
            {
                if (this.CardNumber > other.CardNumber)
                {
                    return 1;
                }
                else if (this.CardNumber < other.CardNumber)
                {
                    return -1;
                }
                else//如果数字相同,则比较枚举值,枚举类型都对应一个数值默认从0开始。
                {
                    if (this.Cardkind > other.Cardkind)
                    {
                        return 1;
                    }
                    else if (this.Cardkind < other.Cardkind)
                    {
                        return -1;
                    }
                    else
                    {
                        return 0;//排面花色都相等
                    }
                }
            }
        }
    

    StartClass.cs

    class StarClass
        {
            public static void Main(string[] args)
            {
                ListCompare lc = new ListCompare(); 
                Console.WriteLine("排序前===========");
                lc.OutputCards(lc.cards);//打印列表
                lc.cards.Sort();//不需要参数
                Console.WriteLine("排序后===========");
                lc.OutputCards(lc.cards);//打印列表
                Console.ReadKey();
            }
        }
    

    输出结果

在这里插入图片描述

根据结果截图可以看出来这两种方法都实现了,扑克牌按数字从小到大排序,如果数字相等则按花色从黑桃, 方块, 红桃到 梅花的排序。

最后总结:List<T>自定义排序可以通过IComparable<T>接口或者IComparer<T>接口实现。

  • IComparable<T>接口实现时需要对象实现接口中的CompareTo()方法。最后调用List.Sort()排序;
  • IComparer<T>接口需要创建比较类,并实现接口中的Compare()方法。最后需要创建比较类的实例,并当作参数传入List.Sort()方法中。

在这里插入图片描述
-------------------------------------------------------------------2020.04.07 晚 天气多云转晴

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!