【c#基础】集合

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

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

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

集合类区别和性能差异:

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

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

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

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

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

【c#基础】集合

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>类型的任意对象传递给类的构造函数。

【c#基础】集合
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()重载方法。

【c#基础】集合

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

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

只读集合

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

可以创建只读集合。

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>接口的其他集合复制到队列中。

【c#基础】集合

上一篇:Kafka API实战


下一篇:Windows下Cython使用(VS2017)