• 【c#基础】集合


    数组和Array类实现的接口 数组大小是固定的。如果元素个数是动态的就应该使用集合类。

    集合类型:List<T> 、队列、栈、链表、字典和集。

    多线程中使用的位数组和并发集合。

    集合类区别和性能差异:

    泛型集合类 在System.Collections.Generic 名称空间中。

    特定类型的集合类 位于System.Collections.Specialized名称空间汇总。

    线程安全的集合类位于System.Collections.Concurrrent名称空间中。

    不可变的集合类在System.Collections.Immutable 命名空间。

    集合可以根据集合类实现的接口组合为列表、集合和字典。

    List<T>泛型-- 如果列表容量改变了,整个集合就要重新分配到一个新的内存块中。

    Array.Copy()方法将数组中的元素复制到新数组中。为节省时间,如果事先知道列表中的元素个数,就可以用构造函数定义其容量。

    //声明一个int泛型集合并初始化一个容量为10的元素集合
    List<int> intList=new List<int>(10);
    //使用Capacity 属性可以获取和设置集合的容量
    intList.Capacity=20;
    

     容量于集合中元素的个数不同。集合中的元素个数可以用Count属性读取 。

    容量 总是大于或等于元素个数。只要不把元素添加到列表中,元素个数就是0。

     如果已经将元素添加到列表中,且不希望添加更多的元素,就可以调用TrimExcess()方法 ,去除不需要的容量。但是,因为重新定位需要时间,所以如果元素个数超过了容量的90%,TrimExcess()方法就什么也不会做。intList.TrimExcess();

    1:集合初始值设定项。

    var intList=new List<int>(){1,2};

    2:添加元素 intList.Add(3);

    使用AddRange()方法 可以一次给集合添加多个元素,因为AddRange()方法的参数是IEnumerable<T>类型的对象,所以也可以传递一个数组。

    如果知道集合元素个数 将可以将实现了IEnumerable<T>类型的任意对象传递给类的构造函数。

    1 var racers=new List<Racer>{
    2     new Racer[]{
    3     new Racer(12,"Jochen","Rindt","Austria",6),
    4    ....
    5    ...
    6    }  
    7 }
    ad

    3:插入元素

    intList.Insert();

    方法 InsertRange()体东了插入大量元素的功能,类似于前面的AddRange()方法。

    如果索引集大于集合中的元素个数,就抛出ArgumentOutRangeException类型。

    4:访问元素

    实现了IList和IList<T>接口的所有类都提供了一个索引器。所以可以使用索引器,通过

    传递元素好来访问元素。

    List<T>集合类实现了IEnumerable接口,所以可以使用foreach遍历元素个数

    for循环遍历,并使用索引器访问每一项。

    可以通过索引访问的集合类有ArrayList、StringCollection和List<T>。

    5:删除元素

    可以利用索引,删除元素。也可以传递要删除的元素 RemoveAt();

    如删除第4个元素 racers.RemoveAt(3);

    也可以直接将Racer对象传送给Remove()方法,来删除这个元素。

    按索引删除比价快,因为必须在集合中搜索要删除的元素。Remove()放在现在集合中搜索,用IndexOf()方法获取元素的索引,在使用该索引删除元素。IndexOf()方法先检查元素类型是否实现

    IEquatable<T>接口。如果是,就调用这个接口的Equals()方法,确定集合中的元素是否等于传递给Equals()方法的元素。如果没有实现这个接口,就使用Object类的Equals()方法比较这些元素。

    Object类中的Equals()方法默认实现代码对值类型进行按位比较,对引用类型只比较其引用。

     RemoveRange()方法可以从集合中删除许多元素。它的第一个参数指定了开始删除的元素指引,第二个参数指定了要删除的元素个数。RemoveRange(index,count);

    要从集合中删除有指定特征的所有元素,可以使用RmoveAll()方法,这个方法在搜索元素时使用Predicate<T>参数。要删除集合中的所有元素,可以使用ICollection<T>接口定义的Clear()方法。

    6:搜索

    要获得要查找的元素的索引,或者搜索元素本身,可以使用方法有IndexOf()、LastIndexOf() FindIndex() FindLastIndex() Find() FindLast().所以只检查元素是否存在,List<T>类就体东了Exists()方法。

    IndexOf()方法需要将一个对象作为参数,如果在集合中找到该元素,这个方法就返回元素的索引,如果没有找到该元素,就返回-1.IndexOf()方法使用IEquatable<T>接口来比较元素。

     使用IndexOf()方法,还可以指定不需要搜索整个集合,但必须指定从哪个索引开始搜索以及比较要迭代的元素个数。

    FindIndex() 方法可以用来搜索某个特征的元素,FindexIndex()方法需要一个

    Predicate类型的参数。

    public int FindIndex(Predicate<T> match);

    Predicate<T>类型时一个委托。该委托返回一个布尔值。并且需要把类型T作为参数。如果

    Predicate<T>委托返回true,就表示有一个匹配元素,并且找到相应的元素。如果没有返回false,就表示没有找到元素,搜索将继续。

    public delegate bool Predicate<T>(T obj);

     FindIndex除了可以用类型T 作为方法参数外。可以用lambda表达式。效果是一样的

    racers.FindIndex(r=>r.Country=="Finland");

    racers.FindIndex(new FindCountry("Finland").FindeCountryPredicate);

    FindLastIndex()方法:从集合汇总的最后一个元素开始向前搜索某个索引。

    FindIndex()方法 返回所查找元素的索引。除了活的索引之外。还可以直接获得集合中的元素。

    FindLast()方法,查找与Predicate<T>类型匹配的最后一项。

    FindAll()方法。FindAll()方法使用的Predicate<T>类型匹配的所有项。FindeAll方法找到第一项后,不会停止搜索,而是继续迭代集合中的每一项。并返回Predicate<T>类型是true的所有项。

    7.排序

    List<T>类可以使用Sort()方案对元素排序。Sort()方法使用快速排序算法。比较所有元素,直接整个列表排好序为止。

    只有集合中的元素实现了IComparable<T>接口,才能使用不带参数的Sort()方法。

    Sort()重载方法。

    如果需要按照元素类型不默认支持的方法排序,就应使用其他技术。

    如传递一个实现了IComparer<T>接口对象。

    Comparsion<T>是一个方法委托,该方法有两个T型参数,返回类型为int型

    public delegate int Comparsion<T>(T x,T y)

    lambda  racers.Sort((r1,r2)=>r2.Wins.CompareTo(r1.Wins));

    调用Reverse()方法,逆转整个集合的顺序

    只读集合

    创建集合后他们就是可读写的。否则就不能给他们填充值了。但是,填充完集合后,

    可以创建只读集合。

    List<T>集合的AsReadOnly()方法返回ReadOnlyCollection<T>类型的对象。

    ReadOnlyCollection<T>类实现的接口与List<T>集合相同。但所有修改集合的方法和属性都抛出NoSupportedException异常。除了List<T>的接口之外,ReadOnlyCollection<T>还实现了IReadOnlyCollection<T>和IReadOnlyList<T>接口。因为这些接口的成员,集合不能修改。

    11.4队列

    队列先进先出(FirstIn,FirstOut FIFO)的方式来处理集合。

    队列的例子 有打印队列中等待处理打打印任务,以及按循环方式等待CPU处理的线程。

    元素还有优先级。

    可以为一组队列建立一个数组,数组中的一项代表一个优先级。在每个数组项中都有一个队列。其中按照FIFO的方式进行处理了。

    队列使用System.Collections.Generic名称空间中的泛型类Queue<T>实现。

    在内部Queue<T>类使用T类型的数组,它实现了ICollection和IEnumerable<T>接口。

    但没有实现ICollection<T>接口 因为这个接口定义的Add()和Remove()方法不能用于队列。

    因为Queue<T>类没有实现IList<T>接口,所以不能用索引器访问队列。队列只允许在队列中添加元素。该元素会放在队列的尾部(使用Enqueue()方法)从队列的头部获取元素(使用Dequeue()方案)。

     Dequeue()会读取和删除元素。如果调用Dequeue()方法时,队列中不再有元素。就抛出一个InvalidOperationException类型的异常。

    Peek()方法从队列的头部读取一个元素,但不删除它。

    TrimExcess TrimExcess()方法重新设置队列的容量,Dequeue()方法从队列中删除元素,但它不会重新设置队列的容量,要重队列的头部去除空元素,应使用TrimExcess()方法。

    泛型Queue没有定义容量,容量就会递增,从而包含4、  8、 16、 32个元素类似于List<T>类 队列的熔炼炉也是总根据需要成倍增加。

    非泛型类Queue的默认构造函数于此不同 它会穿件一个包含32项的空的初始数组。

    使用构造函数的重载版本,还可以将实现了IEnumerable<T>接口的其他集合复制到队列中。

  • 相关阅读:
    3-1
    3-2
    习题二 8
    习题二 3
    习题二 5
    习题二 4
    习题二 6
    实验三-2未完成
    实验三
    心得
  • 原文地址:https://www.cnblogs.com/SignX/p/11247677.html
Copyright © 2020-2023  润新知