集合(Collection):专门用于数据存储和检索的类,用于存放一组数据,和数组类似,可以动态的对集合的长度进行集合长度进行定义和维护,提供了特定方法可以直接操作集合中的数据,并提供了不同集合类来实现特定功能。
集合有关的命名空间是System.Collection,部分常用的接口为:
| 接口名称 | 作用 |
| IEnumerable | 迭代集合中的项,为声明式接口 |
| IEnumerator | 迭代集合中的项,为实现式接口 |
| ICollection | .NET提供的标准集合接口,所以集合类都是直接或间接实现该接口 |
| IList | 继承IEnumerable和ICollection接口,用于提供集合项列表,并允许访问、查找集合中的项 |
| IDictionary | 继承自IEnumerable和ICollection接口,与IList的功能类似,但集合中的项是以键值对(key/value)的形式存在的 |
| IDictionaryEnumerator | 迭代IDictionary接口类型的集合 |
下面是集合中常用的几种数据结构:
第一类:ArrayList——动态数组
代表了可被单独索引的对象的有序集合,基本上可替代一个数组,和数组的操作类似,当使用索引对此进行添加或移除操作,ArrayList会自动调整它的大小(长度)。此外,ArrayList也允许在列表中进行动态内存分配、增加、搜索、排序各项。
创建ArrayList类的对象时需要使用ArrayList类的构造函数,主要有以下三种:
| 构造方法 | 作 用 |
| ArrayList() | 创建实例,容量为默认的初始容量(为0) |
| ArrayList( ICollection c ) | 创建该类实例,实例包含从指定实例中复制的元素,并且初始容量和复制个数一样 |
| ArrayList( int capacity) | 创建实例,并设置初始容量 |
以上构造方法分别举例:
ArrayList list1 = new ArrayList();
ArrayList list2 = new ArrayList(list1);
ArrayList list3 = new ArrayList(10);
备注:创建实例时,集合中并未存放值(元素),若要添加元素,则使用下面格式:
ArrayList list4 = new ArrayList(){1,2,3,4};
遍历集合中的值使用foreach语句,因为集合中的值可以是任意类型,所以使用var关键字,因此查询遍历语句为:
foreach (var v in list4)
{ Console.WriteLine(v) ;}
ArrayList常用的属性和方法见下面链接:
https://blog.csdn.net/qq_42007357/article/details/104278427
注:Sort方法排序时是按照ASCII码进行从小到大排序。
Insert方法每次只能添加一个元素,InsertRange方法可以将一个集合插入到另一个集合中,但可以指定索引处。但Add/AddRange方法只能将元素添加到末尾。
字符串类型的值不能直接使用大于、小于的方法比较,需要使用CompareTo方法,语法形式为:字符串1.CompareTo(字符串2);
比较结果有三种:1.两者相等时,结果为0;
2.当字符串1字符顺序在字符串2前面时,结果为-1;
3.当字符串1字符顺序在字符串2后面时,结果为1。
第二类:Queue——队列(若所存储的第一个对象正是要使用的第一个对象,即先来先服务,则可使用Queue)
一种先进先出的结构,元素从队尾插入(入队),从队头移除(出队)。没有实现 IList,ICollection,因此无法按索引访问元素,不能使用Add和Remove。
下面是常用的构造方法:
| 构造方法 | 作 用 |
| Queue() | 创建实例,容量为默认初始32个元素,默认增长因子 |
| Queue( ICollection col ) | 创建实例,该实例包含从指定实例中复制的元素,初始容量和复制元素个数相同,增长因子一样 |
| Queue( int capacity ) | 创建实例,并设定指定元素个数,默认增长因子 |
| Queue( int capacity , float growFactor) | 创建实例,并设定指定元素个数和增长因子 |
增长因子:当需要扩大容量时,以当前容量(capacity)值乘以增长因子(growFactor)的值来自动增加容量。
以上构造方法分别举例为:
Queue q1 = new Queue();
Queue q2 = new Queue(q1);
Queue q3 = new Queue(20);
Queue q4 = new Queue(20,3);
创建实例时,无法直接赋值。
队列(Queue)中常用的属性和方法主要是下面几种:
| 属性或方法 | 作用 |
| void Clear() | 清除实例中的元素 |
| bool Contains(object obj) | 判断实例中是否包含指定obj元素 |
| void CopyTo(Array array,int index) | 将array数组从指定index索引处元素开始复制到实例中 |
| object Dequeue() | 移除并返回位于Queue实例开始处的对象(在队列的头尾读取并删除一个元素) |
| void Enqueue(object obj) | 将对象添加到实例结尾处 (比较常用) |
| object Peek() | 返回实例开始处的对象但不移除 |
| object[] ToArray() | 将Queue实例中的元素复制到新数组中 |
| IEnumerator GetEnumerator() | 返回循环访问Queue实例的枚举 |
| Count | 属性,获取实例中包含的元素个数 |
注:1. object[] ToArray()的举例为:object[] obj = q1.ToArray();
2.void Enqueue(object obj)方法单次只能添加一个元素,但可以多次使用该方法以达到添加多个元素的目的。
以下是使用部分队列属性方法的代码:
Queue q1 = new Queue(); //创建队列q1
q1.Enqueue("狂人日记");
q1.Enqueue("呐喊");
q1.Enqueue("朝花夕拾");
q1.Enqueue("彷徨"); //向q1中添加四个元素
int i = q1.Count; //创建新变量来使用利用Count属性,获取队列元素个数
Console.WriteLine("队列q1的元素个数:"+i);
foreach(var v in q1)
{
Console.WriteLine(v);
}
Console.WriteLine();//换行
bool bo = q1.Contains("呐喊"); //查询q1是否包含指定元素
if(bo)
{
Console.WriteLine("作品包含指定元素!");
}
else
{
Console.WriteLine("暂无此作品!");
}
Console.WriteLine(); //换行
q1.Dequeue(); //删除第一个元素
foreach(var v in q1)
{
Console.Write(v+" ");
}
Console.ReadLine();第三类:Stack——栈(也称堆栈)
一种后进先出的数据结构。向集合中添加一项元素,称为“推入”元素(入栈),当从集合中移除一项时,称为“弹出”元素(出栈)。最早进入的元素存放的位置叫作栈底 (bottom),最后进入的元素 存放的位置叫作栈顶 (top)。后进先出指的是后面添加的元素会排在集合的顶部也就是最前面,按照从后往前添加元素的规则。
常用的构造方法为:
| 构造方法 | 作 用 |
| stack() | 创建实例,初始容量 |
| stack( ICollection col ) | 创建实例,该实例包含从指定实例中复制的元素,初始容量和复制元素个数相同,增长因子一样 |
| stack( int capcity ) | 创建 Stack 的实例,并设置其初始容量 |
一般特性为:
1)Stack 的容量是指最大可容纳的元素数。添加元素时,会根据需要动态调整容量。
2)如果不使用泛型,则默认元素类型均为 object 类型。
3)无法通过下标查找元素,不能在指定位置插入元素,且不带排序功能。
4)可以添加相同元素,且元素可以为 null 。
stack类常用的属性方法为:
| 属性和方法 | 作用 |
| Push( object obj ) | 向栈中添加元素(入栈) |
| object Peek() | 获取栈顶的值,但不移除 |
| object Pop() | 获取栈顶的值,并且移除 |
| Clear() | 移除所有元素 |
| Contains(object obj) | 判断obj是否存在 |
| object[] ToArray() | 复制stack到数组中 |
注:Count属性对stack类同样适用。
第四类:Hashtable——哈希表(散列表)
用于处理和表现类似key/value的键值对,其中key通常可用来快速查找,同时key是区分大小写;value用于存储对应于key的值。Hashtable中key/value键值对均为object类型,所以Hashtable可以支持任何类型的key/value键值对。
可将其哈希表理解成存放两个数组,一个存放key值,一个存放value值。
使用哈希表的情况:
(1)某些数据会被高频率查询
(2)数据量大
(3)查询字段包含字符串类型
(4)数据类型不唯一
哈希表中常用的构造是不带参数的,即:
Hashtable 对象名 = new Hashtable();
常用的属性和方法:
| 属性、方法 | 作 用 |
| Count | 属性,获取集合中存放元素的个数 |
| void Add(object key,object value) | 添加元素 |
| void Remove(object key) | 根据key值移除元素 |
| void Clear() | 清空集合中的元素 |
| ContainsKey(object key) | 判断集合是否包含指定key值 |
| containsValue(object value) | 判断集合是否包含指定value值 |
部分方法操作的代码如下:
Hashtable hashtable = new Hashtable(); //创建哈希表
hashtable.Add("鲁迅","从百草园到三味书屋");
hashtable.Add("老舍","骆驼祥子");
hashtable.Add("曹雪芹","红楼梦"); //添加三个元素,每个元素都包含key和value
Console.WriteLine("输入作者");
string str = Console.ReadLine();
bool b = hashtable.ContainsKey(str);
if(b==true)
{ //读取输入作者(key)对应的作品(value)
Console.WriteLine("作品为:{0}",hashtable[str]);
}
else
{
Console.WriteLine("暂未找到对应作者,请持续加入");
}
hashtable.Remove("老舍"); //根据给定key删除对应元素
Console.WriteLine("删除指定元素后查询为:");
foreach (DictionaryEntry dt in hashtable) //foreach语句查询集合中剩余元素
{
Console.WriteLine("{0} {1}",dt.Key,dt.Value);
//或者下述语句也行
//Console.WriteLine(dt.Key+" "+dt.Value);
}注:遍历哈希表需要用到DictionaryEntry Object;
遍历键key值时:
foreach (int key in hashtable.Keys)
{
Console.WriteLine(key);
}遍历键value值时:
foreach (string value in hashtable.Values)
{
Console.WriteLine(value);
}对哈希表按key值重新排列并遍历排序后的key的做法:
ArrayList akeys=new ArrayList(hashtable.Keys);
akeys.Sort(); //按字母顺序进行排序
foreach(var v in akeys)
{
Console.WriteLine(v + ": " + hashtable[key]); //排序后输出
}第五类:SortedList——有序列表
实现了IDictionary接口,该集合中的值都是以键值对的形式存取,有序列表是按照键(key)的值进行排序。
SortedList的属性和方法与Hashtable类似。
当SortedList中的元素有变动(增加或移除)时,剩下的元素会自动按照key值进行排序,不需要进行任何动作。