zoukankan      html  css  js  c++  java
  • C#面向对象二(集合泛型及排序)

    1为什么要用集合

      数组的局限性:数组元素个数固定,数组一旦定位就无法改变元素总数,如果有需求变化,则必须修改源码;    如果初始化元素总数非常大,则会造成空间浪费。

      集合的特点:根据需要动态增加个数,没有限制。

    2泛型集合List<T>

      <T>表示泛型,T是Type的简写,表示当前不确定具体类型。

      可以根据用户的实际需要,确定当前集合需要存放的数据类型,一旦确定不可改变。

      使用泛型集合只能添加一种类型的数据,数据取出后无需强制转换。

      使用前引入命名空间:System.Collections.Generic

      常用方法:添加元素Add(<T>),删除元素Remove(索引)  元素个数:Count  使用可以用遍历foreach

      泛型集合的最大特性:严格约束集合内的元素类型

    3泛型集合Dictionary<K,V>

      Dictionary<K,V>通常称为字典,<K,V>约束集合中元素类型。

      编译时检查类型约束,无需拆装箱操作,与哈希表操作类似。

    4List<T>默认排序

      list.Sort();  基本数据类型可以直接排序,对于字符串默认按照拼音首字母升序排列

      调用集合中的Reverse()方法,实现元素反转。

      如果T不是基本数据类型而又想对其排序,T这个类必须继承IComparable<T>这个接口,并且必须对提供泛型接口要实现的方法,这个方法一般直接显示接口,但当此类继承自多个接口时需要显式实现接口。此实现接口方法的签名和返回值类型以及方法名不可更改。

    1         public int CompareTo(Student other)
    2         {
    3             //return other.stuName.CompareTo(this.stuName);   //other在前,降序
    4 
    5             return this.StuId.CompareTo(other.StuId);  //this在前,升序
    6         }    
    IComparable接口

      默认的排序方式,只能有一种。

    5List<T>动态排序

      如果仅对姓名进行升序或学号进行降序等可只用List<T>默认排序。List<T>只有一种排序方式。

      但在实际项目中,可能有时是姓名升序、有时是姓名降序、有时是学号升序、有时是学号降序,需要用到ICompare<T>接口。使用比较器ICompare<T>实现动态排序。

      默认排序可完全被比较器IComPare<T>所替代。

     1     //年龄升序排列
     2     class AgeASC : IComparer<Student>
     3     {
     4         public int Compare(Student x, Student y)
     5         {
     6             return x.Age - y.Age;
     7         }
     8     }
     9     //年龄降序排列
    10     class AgeDESC : IComparer<Student>
    11     {
    12         public int Compare(Student x, Student y)
    13         {
    14             //return y.Age - x.Age;
    15             return y.Age.CompareTo(x.Age);
    16         }
    17     }
    18     //姓名升序排列
    19     class NameASC : IComparer<Student>
    20     {
    21         public int Compare(Student x, Student y)
    22         {
    23             return x.StuName.CompareTo(y.StuName); //x在前,升序
    24         }
    25     }
    26     //姓名降序排列
    27     class NameDESC : IComparer<Student>
    28     {
    29         public int Compare(Student x, Student y)
    30         {
    31             return y.StuName.CompareTo(x.StuName); //y在前,降序
    32         }
    33     }
    IComparer比较器接口

    6总结Sort()方法

    6.1List集合的Sort方法共有4种。

      Sort():使用默认比较器IComparable<T>排序对象。

      Sort(ICompare<T> compare):将实现比较器接口的对象作为参数,这个对象是指继承了此比较器接口的类的对象。

    6.2集合排序总结

      如果是基本数据类型元素,可以直接排序。

      如果是对象类型元素:

        1.当排序只有一种的时候,可以使用默认比较器IComparable<T>在类中直接实现接口即可。

        2.当需要多种排序的时候,需要添加对应排序类,并给每一个排序类实现比较器接口ICompare<T>来完成不同排序方法。

    7使用Linq排序

     1 static void Main(string[] args)
     2         {
     3             //实例化List<T>集合对象
     4             List<Student> list = new List<Student>();
     5             //添加对象元素
     6             Student objStu1 = new Student() { Age = 20, StuId = 1001, StuName = "小张" };
     7             Student objStu2 = new Student() { Age = 25, StuId = 1003, StuName = "小李" };
     8             Student objStu3 = new Student() { Age = 22, StuId = 1002, StuName = "小王" };
     9             list.Add(objStu1);
    10             list.Add(objStu2);
    11             list.Add(objStu3);
    12             //默认排序
    13             Console.WriteLine("------------默认排序------------");
    14             for (int i = 0; i < list.Count; i++)
    15             {
    16                 Console.WriteLine("姓名:{0}  年龄:{1}  学号:{2}", list[i].StuName, list[i].Age, list[i].StuId);
    17             }
    18             //年龄降序排序
    19             Console.WriteLine("------------年龄降序排序------------");
    20             List<Student> stuList = list.OrderByDescending(s => s.Age).ToList();
    21             for (int i = 0; i < stuList.Count; i++)
    22             {
    23                 Console.WriteLine("姓名:{0}  年龄:{1}  学号:{2}", stuList[i].StuName, stuList[i].Age, stuList[i].StuId);
    24             }
    25             //姓名升序排序
    26             Console.WriteLine("------------姓名升序排序------------");
    27             stuList = list.OrderBy(s => s.StuName).ToList();
    28             for (int i = 0; i < list.Count; i++)
    29             {
    30                 Console.WriteLine("姓名:{0}  年龄:{1}  学号:{2}", stuList[i].StuName, stuList[i].Age, stuList[i].StuId);
    31             }
    32             Console.ReadLine();
    33         }
    34         #endregion
    使用LINQ排序

    8.泛型

      8.1可以使用泛型方法、泛型类、泛型接口、泛型委托。泛型类可以被继承,但继承的时候必须指定参数类型;可以在子类中指明参数类型,也可以只在泛型类指明参数类型;泛型接口 继承和泛型类继承是一样的。

      8.2泛型约束:可以是基类约束、接口约束、引用类型约束(T:class)、值类型约束(T:struct)、无参数构造函数约束(T:new())             

      默认值——>>值类型示例  T t = default(T) ;  //前提是值类型,这个default会根据T的不同,赋予默认值

      默认值——>>无参数构造函数约束示例  T t = new T ();

      泛型使用的方法是参数类型未事先指明,任何类型都可以进来,这样做是不安全的。所以这时需要使用到泛型约束。约束可以是基类约束,例如Where T:People,就指明这里的T必须是People,不能Dog/Cat之类的。赋予了T:People,强制保证T一定是People或者People的子类,就可以使用基类的一切属性和方法。

      约束可以叠加,Where T : People,ISports   //表明既可以继承People类,又可以继承ISports接口

      8.3协变和逆变

        public class Bird
        {
            public int Id { get; set; }
        }
    
        public class Sparrow : Bird
        {
            public string Name { get; set; }
        }
    声明两个类:Bird和Sparrow(麻雀),Sparrow继承于Bird
                    Bird bird1 = new Bird();            //声明一只鸟,就是一只鸟,OK
                    Bird bird2 = new Sparrow();         //声明一只鸟,指明它是麻雀,OK
                    Sparrow sparrow1 = new Sparrow();   //声明一只麻雀,就是一只麻雀,OK
                    //Sparrow sparrow2 = new Bird();    //声明一个麻雀,指明它是一只鸟,不OK,因为并不是所有的鸟都是麻雀,也有可能是鹦鹉
    单个变量的声明
                    List<Bird> birdList1 = new List<Bird>();            //OK,声明一群鸟,指明它们就是一群鸟
                    //List<Bird> birdList2 = new List<Sparrow>();       //不OK
                    //声明一群鸟,指明它们就是一群麻雀,道理上行得通,因为一堆麻雀当然是一堆鸟。但C#两个集合对象之间没有父子关系
                    //Bird bird2 = new Sparrow();是OK的,因为Bird与Sparrow之间存在父子关系
                    List<Bird> birdList3 = new List<Sparrow>().Select(c => (Bird)c).ToList();
    List<>变量的声明·
                    IEnumerable<Bird> birdList1 = new List<Bird>();
                    IEnumerable<Bird> birdList2 = new List<Sparrow>();
    
                    Func<Bird> func = new Func<Sparrow>(() => null);
    协变
                    ICustomerListIn<Bird> birdList1 = new CustomerListIn<Bird>();
                    birdList1.Show(new Sparrow());
                    birdList1.Show(new Bird());
    
                    Action<Sparrow> act = new Action<Bird>((Bird i) => { });
    逆变

      

  • 相关阅读:
    Mongo连接远程数据库
    将MongoDB服务器设置成Windows启动服务(win10)
    关于php初学者的理解!请大家浏览并指出不足!谢谢!
    python+selenium初学者常见问题处理
    极客时间测试专栏阅读总结——软件测试总体方案
    pytest 一.安装和使用入门
    软件测试工程师——你不仅仅应该会点点点
    测试电梯、杯子、桌子、洗衣机的方法
    软件测试面试-软件测试宝典
    支付测试场景
  • 原文地址:https://www.cnblogs.com/yangmengke2018/p/10805742.html
Copyright © 2011-2022 走看看