• C#比较类/接口、Dictionary 排序


    
    

    作者:l625208058

    
    

    链接:https://www.jianshu.com/p/cd1be6652570



    先 F12 看下 List.Sort() 方法:
    1 public void Sort(int index, int count, IComparer<T> comparer);  //指定范围排序
    2 public void Sort(Comparison<T> comparison); //Comparison<T>其实就是个委托
    3 public void Sort(); //使用默认排序
    4 public void Sort(IComparer<T> comparer); //使用一个自定义排序者

     

    一. Comparison<T>

     1 public delegate int Comparison<in T>(T x, T y); 

    这其实就是个委托,排序示例:

     1 Dictionary<string, int> dic = new Dictionary<string, int>();
     2 dic.Add("index.html", 50);
     3 dic.Add("product.html", 13);
     4 dic.Add("aboutus.html", 4);
     5 dic.Add("online.aspx", 22);
     6 dic.Add("news.aspx", 18);
     7 
     8 public static int h1(KeyValuePair<string, int> s1, KeyValuePair<string, int> s2)
     9 {
    10     return s2.Value.CompareTo(s1.Value);
    11 }        
    12 
    13 //第一种,使用预先定义的静态方法
    14 List<KeyValuePair<string, int>> list1 = new List<KeyValuePair<string, int>>(dic);
    15 list1.Sort(h1);
    16 
    17 //第二种,使用Dictionary<string, int> dic = new Dictionary<string, int>();
    18 dic.Add("index.html", 50);
    19 dic.Add("product.html", 13);
    20 dic.Add("aboutus.html", 4);
    21 dic.Add("online.aspx", 22);
    22 dic.Add("news.aspx", 18);
    23 
    24 public static int h1(KeyValuePair<string, int> s1, KeyValuePair<string, int> s2)
    25 {
    26     return s2.Value.CompareTo(s1.Value);
    27 }        
    28 
    29 //第一种,使用预先定义的静态方法
    30 List<KeyValuePair<string, int>> list1 = new List<KeyValuePair<string, int>>(dic);
    31 list1.Sort(h1);
    32 
    33 //第二种,使用匿名方法
    34 List<KeyValuePair<string, int>> list2 = new List<KeyValuePair<string, int>>(dic);
    35 list1.Sort(delegate (KeyValuePair<string, int> s1, KeyValuePair<string, int> s2)
    36 {
    37     return s2.Value.CompareTo(s1.Value);
    38 });
    39 
    40 //第三种,使用 lambda 表达式
    41 List<KeyValuePair<string, int>> list3 = new List<KeyValuePair<string, int>>(dic);
    42 list2.Sort((s1, s2) => { return s1.Value.CompareTo(s2.Value); });

    二. Comparer<T>IComparer<T>

      1. 概念:为 IComparer<T> 泛型接口实现提供的基类。

    1 public abstract class Comparer<T> : IComparer, IComparer<T>
    2 {
    3     protected Comparer();
    4     public static Comparer<T> Default { get; }
    5     public static Comparer<T> Create(Comparison<T> comparison);
    6     public abstract int Compare(T x, T y);
    7 }

      2. Comparer<T>和 IComparer<T>的区别:

      • Comparer<T>是类,并提供了默认比较器,也就是说,如果需要自定义默认比较器,需要自行实现IComparer<T>接口
      • 使用Comparer<T>.Default来获取默认比较器
      • IComparer<T> 就是提供一个统一的比较接口,而Comparer<T>就是官方为你提供的一个抽象实现类,具体还是得要你重写实现

    三. IComparable<T>

    自己设计的模型类需要比较,可继承此接口,实现后就可以直接使用排序
    接口类:
    1 public interface IComparable<in T>
    2 {
    3     int CompareTo(T other);
    4 }

    四.Comparer<T> Class、IComparer<T>、IComparable<T>官方案例

      1 class Test
      2 {
      3     static void Main(string[] args)
      4     {
      5         List<Box> Boxes = new List<Box>();
      6         Boxes.Add(new Box(4, 20, 14));
      7         Boxes.Add(new Box(12, 12, 12));
      8         Boxes.Add(new Box(8, 20, 10));
      9         Boxes.Add(new Box(6, 10, 2));
     10         Boxes.Add(new Box(2, 8, 4));
     11         Boxes.Add(new Box(2, 6, 8));
     12         Boxes.Add(new Box(4, 12, 20));
     13         Boxes.Add(new Box(18, 10, 4));
     14         Boxes.Add(new Box(24, 4, 18));
     15         Boxes.Add(new Box(10, 4, 16));
     16         Boxes.Add(new Box(10, 2, 10));
     17         Boxes.Add(new Box(6, 18, 2));
     18         Boxes.Add(new Box(8, 12, 4));
     19         Boxes.Add(new Box(12, 10, 8));
     20         Boxes.Add(new Box(14, 6, 6));
     21         Boxes.Add(new Box(16, 6, 16));
     22         Boxes.Add(new Box(2, 8, 12));
     23         Boxes.Add(new Box(4, 24, 8));
     24         Boxes.Add(new Box(8, 6, 20));
     25         Boxes.Add(new Box(18, 18, 12));
     26 
     27         //使用继承了Comparer<T>的比较器,进行排序。里面覆写了Compare(T a,T b)方法
     28         Boxes.Sort(new BoxLengthFirst());  
     29 
     30         foreach (Box bx in Boxes)
     31         {
     32             Console.WriteLine("{0}	{1}	{2}",
     33                 bx.Height.ToString(), bx.Length.ToString(),
     34                 bx.Width.ToString());
     35         }
     36 
     37         Console.WriteLine("===============");
     38 
     39         //获取默认比较器
     40         Comparer<Box> defComp = Comparer<Box>.Default;  
     41 
     42         // Calling Boxes.Sort() with no parameter
     43         // is the same as calling Boxs.Sort(defComp)
     44         // because they are both using the default comparer.
     45         // 等于调用Boxs.Sort(defComp);
     46         Boxes.Sort();
     47 
     48         foreach (Box bx in Boxes)
     49         {
     50             //输出高、长、宽
     51             Console.WriteLine("{0}	{1}	{2}",
     52                 bx.Height.ToString(), bx.Length.ToString(),
     53                 bx.Width.ToString());
     54         }
     55 
     56         // This explicit interface implementation
     57         // compares first by the length.
     58         // Returns -1 because the length of BoxA
     59         // is less than the length of BoxB.
     60         BoxLengthFirst LengthFirst = new BoxLengthFirst();
     61 
     62         Comparer<Box> bc = (Comparer<Box>)LengthFirst;
     63 
     64         Box BoxA = new Box(2, 6, 8);
     65         Box BoxB = new Box(10, 12, 14);
     66         int x = LengthFirst.Compare(BoxA, BoxB);
     67         Console.WriteLine();
     68         Console.WriteLine(x.ToString());
     69  
     70         Console.ReadLine();
     71     }
     72 }
     73 public class BoxLengthFirst : Comparer<Box>
     74 {
     75     //父类抽象方法 Compare
     76     // Compares by Length, Height, and Width.
     77     public override int Compare(Box x, Box y)
     78     {
     79         if (x.Length.CompareTo(y.Length) != 0)
     80         {
     81             return x.Length.CompareTo(y.Length);
     82         }
     83         else if (x.Height.CompareTo(y.Height) != 0)
     84         {
     85             return x.Height.CompareTo(y.Height);
     86         }
     87         else if (x.Width.CompareTo(y.Width) != 0)
     88         {
     89             return x.Width.CompareTo(y.Width);
     90         }
     91         else
     92         {
     93             return 0;
     94         }
     95     }
     96 
     97 }
     98 
     99 
    100 // This class is not demonstrated in the Main method
    101 // and is provided only to show how to implement
    102 // the interface. It is recommended to derive
    103 // from Comparer<T> instead of implementing IComparer<T>.
    104 
    105 //没有在Main方法里演示,推荐使用继承Comparer<T>的方法。
    106 public class BoxComp : IComparer<Box>
    107 {
    108     // Compares by Height, Length, and Width.
    109     public int Compare(Box x, Box y)
    110     {
    111         if (x.Height.CompareTo(y.Height) != 0)
    112         {
    113             return x.Height.CompareTo(y.Height);
    114         }
    115         else if (x.Length.CompareTo(y.Length) != 0)
    116         {
    117             return x.Length.CompareTo(y.Length);
    118         }
    119         else if (x.Width.CompareTo(y.Width) != 0)
    120         {
    121             return x.Width.CompareTo(y.Width);
    122         }
    123         else
    124         {
    125             return 0;
    126         }
    127     }
    128 }
    129 
    130 public class Box : IComparable<Box>
    131 {
    132     public Box(int h, int l, int w)
    133     {
    134         this.Height = h;
    135         this.Length = l;
    136         this.Width = w;
    137     }
    138     public int Height { get; private set; }
    139     public int Length { get; private set; }
    140     public int Width { get; private set; }
    141 
    142     public int CompareTo(Box other)
    143     {
    144         // Compares Height, Length, and Width.
    145         if (this.Height.CompareTo(other.Height) != 0)
    146         {
    147             return this.Height.CompareTo(other.Height);
    148         }
    149         else if (this.Length.CompareTo(other.Length) != 0)
    150         {
    151             return this.Length.CompareTo(other.Length);
    152         }
    153         else if (this.Width.CompareTo(other.Width) != 0)
    154         {
    155             return this.Width.CompareTo(other.Width);
    156         }
    157         else
    158         {
    159             return 0;
    160         }
    161     }
    162 }

    五. Comparison<T>、 Comparer<T>、 System.IComparable、IComparable<T>的区别

    1. Comparison<T>,继承委托。开发人员可以在外部写个用于比较大小的函数,然后作为 Comparison<T>类型的参数传入,进行比较,非常方便。

    2. 派生自 Comparer<T> 类和实现 System.IComparable 接口之间的差异如下:

    • 若要指定默认情况下(Default获取)应如何比较两个对象,请在类中实现 System.IComparable 接口。 这可确保排序操作将使用您提供的默认比较代码。

    • 若要定义要使用的比较器而不是默认比较器,请从 Comparer<T> 类派生。 然后,您可以在采用比较器作为参数的排序操作中使用此比较器。

    1. Default 属性返回的对象使用 System.IComparable<T> 泛型接口来比较两个对象。 如果类型 T 未实现 System.IComparable<T> 泛型接口,Default 属性返回使用 System.IComparable 接口的 Comparer<T>

  • 相关阅读:
    Eclipse安装Pydev插件时所遇到的问题
    打开Eclipse弹出“No java virtual machine was found..."的解决方法
    使用adb报错;error: unknown host service
    itools安装程序无法创建临时文件夹
    多线程十二之ConcurrentHashMap1.8实现分析
    多线程十一之ConcurrentHashMap1.7源码分析
    多线程十之CopyOnWriteArrayList源码分析
    多线程学习笔记九之ThreadLocal
    多线程学习笔记八之线程池ThreadPoolExecutor实现分析
    多线程学习笔记七之信号量Semaphore
  • 原文地址:https://www.cnblogs.com/fires/p/12995754.html
Copyright © 2020-2023  润新知