集合,表示可以通过遍历每个元素来访问的一组对象(特别是可使用foreach循环访问)。
集合是一组可变数量的数据项(也可能是0个)的组合,这些数据项可能共享某些特征,需要以某种操作方式一起进行操作。一般来讲,这些数据项的类型是相同的,或基类相同(若使用的语言支持继承)。列表(或数组)通常不被认为是集合,因为其大小固定,但事实上它常常在实现中作为某些形式的集合使用。集合的种类包括列表,集,多重集,树和图。枚举类型可以是列表或集。
集合的功能常常通过接口的实现而实现。常用的接口类型如下。
1.System.Colloctions中表示集合的行为的接口有:
1)ICollection
定义所有集合的大小、枚举数和同步方法。派生于IEnumerable
它定义了集合类最基本的行为,所有的集合类都实现了这个接口(基接口)
但是它的行为太过基本:主要就是一个Count属性,单独实现它没有太大意义
2)IEnumerable
公开枚举数,该枚举数支持在集合上进行简单迭代
它只有一个方法 GetEnumerator(),该方法可以返回一个IEnumerator接口,通过它可以遍历集合
基本上所有的集合类都实现了这个接口
3)IList
IList实现是可排序且可按照索引访问其成员的值的集合,它本身实现了ICollection和IEnumerable接口
是所有列表的抽象基类。IList 实现有三种类别:只读、固定大小、可变大小。
4)IDictionary
IDictionary实现是键/值对的集合,它本身实现了ICollection和IEnumerable接口
是键/值对的集合的基接口。IDictionary 实现有三种类别:只读、固定大小、可变大小。
IDictionary可称为字典、映射或散列表,它根据键(任意类型)来访问值
2.System.Collections中可以直接使用的集合类有:
1)ArrayList
实现了接口:IList、ICollection、IEnumerable
只要集合未被修改,ArrayList 就可安全地同时支持多个读取器
随着向 ArrayList 中添加元素,容量通过重新分配按需自动增加(2倍增加)
如果需要建立一个对象数组,但不能预先知道数组的大小,就可以使用ArrayList
ArrayList把所有元素都当作object对象引用,因而在访问ArrayList的元素时要进行类型转换
优点:动态改变大小、灵活方便的插入和删除元素、可排序
缺点:插入时性能不如数组、不是强类型的
2)BitArray
实现了接口:ICollection、IEnumerable
管理位值的压缩数组。
3)Hashtable
实现了接口:IDictionary、ICollection、IEnumerable
可以向Hashtable中自由添加和删除元素,有些像ArrayList,但没有那么大的性能开销
4)SortedList
实现了接口:IDictionary、ICollection、IEnumerable
SortedLIst兼顾了ArrayList和Hashtable的优点,可按键值来排序
5)Queue
实现了接口:ICollection、IEnumerable
Queque是队列,先进先出的访问各个元素
可以调用Queque对象的GetEnumerator()方法,得到IEnumerator对象,来遍历队列中的各个元素
6)Stack
实现了接口:ICollection、IEnumerable
Stack是堆栈,后进先出的访问各个元素
可以调用Stack对象的GetEnumerator()方法,得到IEnumerator对象,来遍历堆栈中的各个元素
3.上面提到的几种集合类,他们都是通用的集合类,他们所接受的元素大都是Object类型,当对象放入
了集合之后,都失去了原有的类型信息-即这些通用集合类都不是强类型的
解决办法是使用强类型的集合类
System.Collections命名空间下的CollectionBase,DictionaryBase,ReadOnlyCollectionBase 类
System.Collections.Specialized命名空间下的一些类可以满足要求,可以直接使用也可以继承。
在声明一个列表时,可以使用如下形式:
List<类型>列表名
其中类型可以是基类型,也可以是用户自定义的类型。
当需要向列中添加元素时,可以使用List<T>类的Add()方法。Add()方法的参数是需要添加的元素对象。
IndexOf(),用于搜索列表中元素的索引号
LastIndexOf(),用于搜索列表中指定元素的最后一个索引号
FindIndex(),用于检索元素在列表中出现的一个位置
FindLastIndex(),用于检索元素在列表中出现的最后一位置
Find(),搜索列表中匹配的第一个对象
FindLast(),搜索列表中匹配的最后一个对象
当需要对列表元素进行排序时,可以使用Sort()方法
利用Reverse()方法可以对列表中的元素逆序
队列
Queue和Queue<T>类的方法
Enqueue(),在队列一端添加一个元素
Dequeue(),在队列的头部读取和删除一个元素。如果在调用Dequeu()方法时,队列中不再有元素,就抛出InvalidOperationExceptio
Peek(),在队列的头部读取一个元素,但不删除它
Count(),返回队列中的元素个数
TrimeExcess(),重新设置队列的容量。Dequeue()方法从队列中删除元素,但不会重新设置队列容量。要从队列的头部去除空元素,使用TrimeExcess()方法。
Contains(),确定某个元素是否在队列中,如果是,返回true
CopyTo(),把元素从队列复制到一个已有数组中。
ToArray(),返回一个包含队列元素的新数组。
栈
栈(Stack)是限制仅在表的一端进行插入和删除运算的线性表。栈通常具有如下特性:
通常称插入、删除在这一端为栈顶(Pop),另一端为栈底(Bottom);
当表中没有元素时称为空栈;
栈为先进后出的线性表。
.Net FrameWork提供了两个类,即Stack和Stack<T>,用于支持对栈的操作,其典型的方法如下:
Push();在栈顶添加一个元素。
Pop();从栈顶删除一个元素,并返回该元素。如果栈为空,就抛出InvalidOperationExceptio
Peek();返回栈顶元素,但不删除它
Count();返回栈中元素的个数
Contains();确定某个元素是来吧在栈中,如是,就返回true
CopyTo()和ToArray(),是把元素从栈中复制到一个已有的数组中。ToArray()方法返回一个包含栈中元素的新数组。
栈表
在.Net Framework中,LinkedList<T>是一个双向链表数据结构。链表不但可以存储元素,还可以存储其前一个和后一个元素的引用信息。
LinkedListNode<T>属性
List,返回与节点相关的LinkedList<T>
Next,返回当前节点之后的节点,其返回类型为LinkedListNode<T>
Previous,返回当前节点之前的节点
Value,返回与节点相关的元素,其类型是T
LinkedList<T>类提供的常见属性和方法
Count,返回链表中的元素个数
First,返回链表中的第一个节点,其返回类型是LinkedListNode<T>.使用这个返回的节点,可以迭代集合其他节点。
Last,返回链表中的最后一个元素,其返回类型是LinkedListNode<T>
AddAfter()、AddBefore()、AddFirst()、AddLast()使用AddXXX方法可以在链表中添加元素。使用相应的Add方法,可以在链表的指定位置添加元素。AddAfter()需要一个LinkedListNode<T>对象,在该对象中可以指定要添加的新元素后面的节点。AddBefore()把新元素放在第一个参数定义的节点前面。AddFirst()和AddLast()把新元素添加到链表的开头和结尾。重载所有这些方法来接收任意的一个对象以添加类型LinkedListNode<T>或类型T。如果传送T对象,建一个新LinkedListNode<T>对象
Remove()、RemoveFirst()、RemoveLast()使用这些方法可以从链表中删除节点。RemoveFirst()删除第一个元素,RemoveLast()删除最后一个元素。Remove()需要搜索一个对象,从链表中删除匹配该对象的第一个节点。
Clear()从链表中删除所有的节点
Contains()从链表中搜索一个元素,如果找到该元素,就返回true,否则返回false
Find()从链表的开头开始搜索传送给它的元素,并返回一个LinkedListNode<T>
FindLast()与Find()方法相似,但从链表的结尾开始搜索。
链表不仅能在列表中存储元素,还可以给每个元素存储下一个元素和上一个元素的信息。
链表的优点是,如果将元素插入列表的中间位置,使用链表会非常快。在插入一个元素时,只需修改上一个元素的Next引用和下一个元素的Previous引用,使它们引用所插入的元素。
链表的缺点是链表的元素只能一个接一个地访问,这需要较长的时间来查找位于链表中间或尾部的元素。
有序表
有序表(SortedList)是其元素已经排好了序的列表,C#这个类是按照键进行排序的。
有序表(SortedList)支持通过由Keys和Value属性返回的集合对键和值执行高效的索引检索。访问此属性无须重新生成列表,因为列表只是键和值的内部数组的包装。
SortedList<Tkey,Tvalue>类的属性
Capacity,使用Capacity属性可以以获取和设置有序表能包含的元素个数。该属性与List<T>类似,默认构造函数会创建一个空表,添加一个元素会使有序表的容量变成4个元素,之后其容量会根据需要成倍的增长。
Comparer,Comparer属性返回与有序表相关的比较器,可以在构造函数中传送该比较器。默认的比较器会调用Icomparable<Tkey>接口的CompareTo()方法来比较键。键类型执行了这个接口,也可以创建定制的比较器。
Count,Count属性返回有序表的元素个数
Item,使用索引器可以访问有序表中的元素。索引器的参数类型由键类型定义
Keys,Keys属性返回包含所有键的Ilist<TKey>
Values,values属性返回包含所有值的Ilist<Tvalue>
SortedList<T>类型的方法
Add(),把带有键和值的元素放在有序表中
Remove(),RemoveAt():Remove()方法需要从有序表中删除的元素的键。使用RemoveAt()方法可以删除指定索引的元素
Clear()删除有序表中的所有元素
ContainsKey()和ContainsValue():ContainsKey()和ContainsValue()方法检查有序表是否包含指定的键和值,并返回true或false
IndexOfKey(),IndexOfValue():IndexOfKey()和IndexOfValue()方法检查是否包含指定的键或值,并返回基于整数的索引
TrimExcess():重新设置集合的大小,将容量改为需要的元素个数
TryGetValue():使用TryGetValue()方法可以尝试获得指定键的值。如果键不存在,这个方法就返回false。如果键存在就返回true,并把值返回为out参数
位数组
位数组(BitArray)可以以数组的方式处理许多工位。C#提供了BitArray类,它位于命名空间System.Collection中,用于实现对位数组的操作。
BitArray类是一个引用类型,包含了一个int数组,每32位使用一个新整数。
BitArray类的类成员说明:
Count,Length:Count和Length的get访问器返回数组中的位数.使用Length属性还可以定义新的数组大小,重新设置集合的大小。
Item:可以使用索引器读写数组中的位。索引器是bool类型。
Get(),Set():除了使用索引器外,还可使用Get和Set方法访问数组中的位
SetAll():根据传送给该方法的参数,设置所有位的值
Not():倒转数组中所有位的值
And(),Or(),Xor():使用And()、Or和Xor()方法,可以合并两个BitArray对象。And()方法执行二进制的AND,只有两个输入数组的位置都设置为1,结果位才是1.Or()方法执行二进制的OR,只要有一个输入数组的位设置为1,结果位就是1.Xor()方法是异或操作,只有一个输入数组的位设置为1,结果才为1。
数组列表
数组列表是一种变长数组,我们可以不断向ArrayList中添加元素,数组列表(ArrayList)容量也会自动增长。在C#中,数组列表(ArrarList)通过System.Collections.ArrayList类来实现。类似于其他集合类型,对于数组列表,可以使用Count属性获得数据列表的长度;使用Add()方法添加元素;使用Index()查询元素;使用Remove()方法删除元素;使用Sort()Sort()方法对元素进行排序。
集合中索引的设定方法。即索引是作为集合的一个属性定义的,故与属性的定义方法类似,且使用this关键字。
public class
infoindex : IEnumerable<infolocation>
{
public
IList<infolocation> List {
get
;
set
; }
public
infolocation
this
[
int
infoindex]
{
get
{
return
this
.List[infoindex];
}
set
{
this
.List[infoindex] = value;
}
}
public
IEnumerator<infolocation> GetEnumerator()
{
return
this
.List.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return
this
.List.GetEnumerator();
}
}