C#List集合實現對對象自定義排序

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 晚 天氣多雲轉晴

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章