认识集合
什么是集合呢?
集合就如同数组,用来存储和管理一组具有相同性质的对象,除了基本的数据处理功能,集合直接提供了各种数据结构及算法的实现,如队列、链表、排序等,可以让用户轻易地完成复杂的数据操作。集合也是一个特殊的类,好比容器一样将一系列相似的项组合在一起,集合中包含的对象称为集合元素。
- 集合类的概念
集合(Collection)类是专门用于数据存储和检索的类。这些类提供了堆栈(stack)、队列(queue)、列表(list)和哈希表(hashtable)的支持。大多数集合类实现了相同的接口。 - 集合类的特点
(1) 集合类定义为System.Collections或Systen.Collections.Generic命名空间的一部分。
(2) 大多数集合类都派生自ICollection、IComparer、IEnumerable、IList、IDictionary和IDictionaryEnumerator接口以及它们的等效泛型接口
(3) 使用泛型集合类可以提供更高的类型安全性,在某些情况下还可以提供更好的性能,尤其是在存储值类型时,这些优势会体现得更明显。
常用的集合类型有动态数组(ArrayList类)、堆栈(Stack类)、Queue类和Hashtable类。
动态数组(ArrayList类)
动态数组(ArrayList)代表了可被单独索引的对象的有序集合。它基本上可以替代一个数组。但是,与数组不同的是,用户可以使用索引在指定的位置添加和移除项目,动态数组会自动重新调整它的大小。它也允许在列表中进行动态内存分配、增加、搜索、排序各项。
下表列出了ArrayList类的一些常用的属性。
下表列出了ArrayList类的一些常用的方法。
ArrayList类中元素的添加
编写程序,创建ArrayList实例,使其固定大小为5,通过Add方法对其添加5个元素,再通过AddRange方法对其添加一个数组,然后遍历所有数元素。
using System;
using System.Collections; //在命名空间进行引用
namespace Project1
{
class Program
{
static void Main(string[] args)
{
ArrayList al = new ArrayList(5); //创建ArrayList的实例,使其固定大小为5
// ArrayList的好处是,长度不固定,类型随意
//数组的长度是固定的,不能更改的,类型单一,只能为其中的一种
Console.WriteLine("------------Count属性----------------");
Console.WriteLine("查看ArrayList中实际包含的元素个数:{0}",al.Count);
Console.WriteLine("-------------Add方法-----------------");
//Console.WriteLine("al初始化之后有{0}个元素",al.Count);//使用Count属性,查看ArrayList中实际包含的元素个数。
//Add方法用于向ArrayList中添加单个元素,每次只能添加一个
al.Add(110); //整数类型
al.Add('M'); //字符类型
al.Add("HelloWorld"); //string类型
al.Add(3.14); //浮点类型
al.Add(24L); //长整型
Console.WriteLine("使用Add方法添加5个元素之后,元素的个数:",al.Count);
Console.WriteLine("------------AddRange方法--------------");//AddRange方法用于一次性向ArrayList中添加多个元素,可以是一个数组
string[] myStringAL = { "张三", "李四", "王五", "赵六" };//定义字符串数组
al.AddRange(myStringAL);
Console.WriteLine("使用AddRange方法添加4个元素后,元素的个数:{0}",al.Count);
Console.WriteLine("--------------遍历集合----------------");
//遍历集合元素
//引用类型 string object类是所有类型的基类
foreach (object outstring in al) //首先定义一个任意类型的变量object,
{
Console.Write(outstring+"\t"); //按行来输出
}
Console.WriteLine();
Console.ReadKey();
}
}
}
【程序分析】本例演示了动态数组元素的添加。在代码中,首先需要引入命名空间“System.Collections;”,因为ArrayList类就在该命名空间中;接着,创建ArrayList的实例al,使其固定大小为5;然后使用Count属性,查看ArrayList中实际包含的元素个数,并使用Add方法向ArrayList中依次添加5个元素;再使用AddRange方法,一次性向ArrayList中添加4个元素。需要注意的是,Add方法每次只能添加一个元素,而AddRange方法一次性可以添加多个元素,或者是一个数组;最后,在遍历集合元素时,可以使用foreach语句,由于ArrayList中可以添加任意类型的元素,所以需要声明一个object类型的变量。
------------Count属性----------------
查看ArrayList中实际包含的元素个数:0
-------------Add方法-----------------
使用Add方法添加5个元素之后,元素的个数:
------------AddRange方法--------------
使用AddRange方法添加4个元素后,元素的个数:9
--------------遍历集合----------------
110 M HelloWorld 3.14 24 张三 李四 王五 赵六
ArrayList类中元素的删除
编写程序,对ArrayList中的元素进行删除
using System;
using System.Collections; //在命名空间进行引用
namespace Project2
{
class Program
{
static void Main(string[] args)
{
//元素的删除有四种方法
//Remove()
ArrayList al = new ArrayList(); //实例化对象
al.Add("小组评分:");
al.Add(88.5);
al.Add("小组成员:");
string[] myStringAL = { "张三", "李四", "王五", "赵六" };
al.AddRange(myStringAL);
foreach (object outArry in al)
{
Console.Write(outArry+"\t");
}
Console.WriteLine("\n------------Remove方法----------------");//Remove(值)
Console.WriteLine("指定对象,移除张三");
al.Remove("张三");
foreach (object outArry in al)
{
Console.Write(outArry + "\t");
}
Console.WriteLine("\n-----------RemoveAt方法---------------");//RemoveAt(索引值)
Console.WriteLine("指定索引值,移除李四");
al.RemoveAt(3);
foreach (object outArry in al)
{
Console.Write(outArry + "\t");
}
Console.WriteLine("\n-----------RemoveRange方法------------");//RemoveRange(开始索引值,要删除的个数)
Console.WriteLine("指定某个范围,移除王五和赵六");
al.RemoveRange(3, 2);//从第三元素开始,删除两个元素
foreach (object outArry in al)
{
Console.Write(outArry + "\t");
}
Console.WriteLine("\n-----------Clear方法------------");
Console.WriteLine("清除所有元素");
al.Clear();
foreach (object outArry in al)
{
Console.Write(outArry + "\t");
}
Console.WriteLine();
Console.ReadKey();
}
}
}
【程序分析】本例演示了元素的删除。在代码中,首先引入命名空间“System.Collections;”,并实例化对象al;接着,使用Add和AddRange方法,依次对ArrayList添加元素;最后,分别使用Remove方法、RemoveAt方法、RemoveRange方法和Clear方法,删除ArrayList中的元素。
小组评分: 88.5 小组成员: 张三 李四 王五 赵六
------------Remove方法----------------
指定对象,移除张三
小组评分: 88.5 小组成员: 李四 王五 赵六
-----------RemoveAt方法---------------
指定索引值,移除李四
小组评分: 88.5 小组成员: 王五 赵六
-----------RemoveRange方法------------
指定某个范围,移除王五和赵六
小组评分: 88.5 小组成员:
-----------Clear方法------------
清除所有元素
ArrayList类中元素的遍历与查找
编写程序,对ArrayList中的元素进行查找和遍历。
using System;
using System.Collections;
namespace Project3
{
class Program
{
static void Main(string[] args)
{
ArrayList al = new ArrayList();
al.Add("数组:");
int[] alInArry = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
al.AddRange(alInArry);
al.Add("字符串:");
string[] alStringArry = { "张三", "李四", "王五", "赵六","李四" };
al.AddRange(alStringArry);
Console.WriteLine("------------遍历元素----------------");
foreach (object outArry in al)
{
Console.Write(outArry+" ");
}
Console.WriteLine("\n------------查找元素----------------");
Console.WriteLine("\n-----------IndexOf方法--------------");
//IndexOf(要查找的元素),返回一个首次出现的索引整型值,如果查找不到,返回-1
Console.WriteLine(al.IndexOf("李四"));
Console.WriteLine("\n----------LastIndexOf方法-----------");
//LastIndexOf(要查找的元素),返回一个最后一次出现的索引整型值,否则返回-1
Console.WriteLine(al.LastIndexOf("李四"));
Console.ReadKey();
}
}
}
【程序分析】本例演示了元素的遍历与查找。在代码中,首先实例化对象al。接着使用Add方法与AddRange方法往ArrayList中添加元素,并使用foreach语句遍历出该数组;然后,使用IndexOf方法,返回一个首次出现“李四”元素的索引值;再使用LastIndexOf方法,返回一个最后一次出现“李四”元素的索引整型值,如果找不到,就返回-1。
------------遍历元素----------------
数组: 1 2 3 4 5 6 7 8 9 字符串: 张三 李四 王五 赵六 李四
------------查找元素----------------
-----------IndexOf方法--------------
12
----------LastIndexOf方法-----------
15
堆栈(Stack类)
堆栈(Stack)代表了一个后进先出的对象集合。当用户需要对各项进行后进先出的访问时,则使用堆栈。当用户在列表中添加一项,称为推入元素,当用户从列表中移除一项时,称为弹出元素。
下表列出了Stack类的一些常用的方法。
using System;
using System.Collections;
namespace Project4
{
class Program
{
static void Main(string[] args)
{
Stack st = new Stack(); //实例化st的对象
Console.WriteLine("------------Push方法----------------");
Console.WriteLine("向堆栈的顶部添加四个对象");
st.Push('a');
st.Push('b');
st.Push('c');
st.Push('d');
Console.WriteLine("------------遍历Stack---------------");
foreach (char c in st)
{
Console.Write(c + " ");
}
Console.WriteLine();
Console.WriteLine("向堆栈的顶部添加两个对象");
st.Push('V');
st.Push('H');
foreach (char c in st)
{
Console.Write(c + " ");
}
Console.WriteLine("\n------------Peek方法----------------");
Console.WriteLine("堆栈顶部的对象:{0}",st.Peek());
Console.WriteLine("--------------Pop方法---------------");
Console.WriteLine("移除堆栈顶部的对象:{0}",st.Pop());
foreach (char c in st)
{
Console.Write(c + " ");
}
Console.WriteLine("\n移除堆栈顶部的对象:{0}", st.Pop());
foreach (char c in st)
{
Console.Write(c + " ");
}
Console.WriteLine();
Console.ReadKey();
}
}
}
【程序分析】本例演示了Stack类的一些使用方法。在代码中,首先实例化堆栈的对象st。接着使用Push方法,往堆栈放入4个对象,并进行遍历;再使用Push方法,往堆栈中放入两个对象,进行遍历;然后使用Pop方法弹出堆栈中的两个对象。此时,用户可以发现,堆栈的特点是先进后出。
------------Push方法----------------
向堆栈的顶部添加四个对象
------------遍历Stack---------------
d c b a
向堆栈的顶部添加两个对象
H V d c b a
------------Peek方法----------------
堆栈顶部的对象:H
--------------Pop方法---------------
移除堆栈顶部的对象:H
V d c b a
移除堆栈顶部的对象:V
d c b a
编写程序,实现堆栈的进出。
Queue类
队列(Queue)代表了一个先进先出的对象集合。当用户需要对各项进行先进先出的访问时,则使用队列。当用户在列表中添加一项,称为入队,当用户从列表中移除一项时,称为出队。
下表列出了Queue类的一些常用的方法。
编写程序 ,实现队列的进出。
using System;
using System.Collections;
namespace Project5
{
class Program
{
static void Main(string[] args)
{
Queue q = new Queue(); //创建一个队列
Console.WriteLine("------------Enqueue方法----------------");
Console.WriteLine("向队列的末尾依次添加对象");
q.Enqueue('a');
q.Enqueue('b');
q.Enqueue('c');
q.Enqueue('d');
Console.WriteLine("--------------遍历队列-----------------");
foreach (char c in q)
{
Console.Write(c + " ");
}
Console.WriteLine("\n向队列的末尾再添加两个对象");
q.Enqueue('V');
q.Enqueue('H');
foreach (char c in q)
{
Console.Write(c + " ");
}
Console.WriteLine();
Console.WriteLine("------------Dequeue方法----------------");
Console.WriteLine("移除队列开头的两个对象");
char ch = (char)q.Dequeue();
Console.WriteLine("移除开头第一个对象: {0}", ch);
ch = (char)q.Dequeue();
Console.WriteLine("移除开头第二个对象: {0}", ch);
Console.WriteLine("--------------遍历队列-----------------");
foreach (char c in q)
{
Console.Write(c + " ");
}
Console.WriteLine();
Console.ReadKey();
}
}
}
【程序分析】本例演示了Queue类的一些使用方法。在代码中,首先实例化队列的对象q,接着使用Enqueue方法,往队列中依次放入6个对象,再使用Dequeue方法移除队列中的两个元素。通过与堆栈对比,用户可以发现,队列元素具有先进先出的特点。
------------Enqueue方法----------------
向队列的末尾依次添加对象
--------------遍历队列-----------------
a b c d
向队列的末尾再添加两个对象
a b c d V H
------------Dequeue方法----------------
移除队列开头的两个对象
移除开头第一个对象: a
移除开头第二个对象: b
--------------遍历队列-----------------
c d V H
Hashtable类
Hashtable被称作哈希表,键值对或者关联数组。用于处理和表现类似key/value的键值对,其中key通常可用来快速查找,同时key是区分大小写;value用于存储对应于key的值。
Hashtable中key/value键值对均为object类型,所以Hashtable可以支持任何类型的key/value键值对。Hashtable中的每个元素是一个存储在DictionaryEntry对象中的键值对。
下表列出了Hashtable类的一些常用的属性。
下表列出了Hashtable类的一些常用的方法。
Hashtable类中元素的添加
**编写程序,**新建一个Hashtable对象,向其中添加三个元素。
using System;
using System.Collections;
namespace Project6
{
class Program
{
static void Main(string[] args)
{
Hashtable ht = new Hashtable();
Console.WriteLine("------------元素添加方法一----------------");
ht.Add(1, "星期一");
ht.Add(2, "星期二");
ht.Add(3, "星期三");
ICollection key = ht.Keys; //获取键值
foreach (object k in key)
{
Console.WriteLine(k + ": " + ht[k]);
}
//用此种方法对Hashtable去增加元素时,应该注意:
//如果对应的键key,存值,只达到一种重新赋值的结果
//如果不存在,才会增加对应的键值对
Console.WriteLine("------------元素添加方法二----------------");
ht[4] = "星期四";
ht[1] = "星期五";
foreach (object k in key)
{
Console.WriteLine(k + ": " + ht[k]);
}
Console.WriteLine("---------------Count属性------------------");
Console.WriteLine("哈希表包含键值对的个数:{0}", ht.Count);
Console.ReadKey();
}
}
}
【程序分析】本例演示了哈希表元素添加的两种方法。在代码中,首先创建对象ht;然后使用第一种方法调用Add增加三个元素;再使用第二种方法,增加了两个元素,用此种方法对Hashtable去增加元素时,应该注意:如果对应的键key已经存值,就会达到一种重新赋值的结果;如果没有存值,才会增加对应的键值对。
因此,在语句“ht[1] = “星期五”;”中,key值为1,value值为“星期五”;而语句“ht.Add(1, “星期一”);”中key值为1,value值为“星期一”。所以运行程序后,“星期一”被“星期五”覆盖了。最后使用Count属性获取Hashtable中包含键值对的个数为4。
------------元素添加方法一----------------
3: 星期三
2: 星期二
1: 星期一
------------元素添加方法二----------------
4: 星期四
3: 星期三
2: 星期二
1: 星期五
---------------Count属性------------------
哈希表包含键值对的个数:4
Hashtable元素的遍历
数组的遍历通常都采用的是for循环语句,但是对于集合的遍历都是采用foreach语句。在C#语言中的foreach语句需要集合中每个元素的类型。由于IDictionary接口是键/值对的非泛型集合的基接口,而每个元素都是键/值对,并存储在DictionaryEntry对象中,因此元素类型既不是键的类型,也不是值的类型,而是DictionaryEntry类型。
编写程序,新建Hashtable的对象,向其中添加四个元素,使用foreach进行遍历。
using System;
using System.Collections;
namespace Project7
{
class Program
{
static void Main(string[] args)
{
Hashtable ht = new Hashtable();
ht.Add(1, "星期一");
ht.Add(2, "星期二");
ht.Add(3, "星期三");
ht[4] = "星期四";
Console.WriteLine("-------------方法一------------");
foreach (DictionaryEntry obj in ht)
{
Console.WriteLine("键为:{0};值为:{1}",obj.Key,obj.Value);
}
Console.WriteLine("-------------方法二------------");
foreach (object obj in ht.Keys) //键的集合
{
Console.WriteLine("键为:{0};值为:{1}", obj, ht[obj]);
}
Console.ReadKey();
}
}
}
【程序分析】本例演示了遍历哈希表的两种方法。在代码中,首先创建对象ht,并添加四个元素;接着使用第一种方法进行遍历,将foreach语句中的变量obj声明为DictionaryEntry类型,并调用Key和Value进行遍历;然后使用第二种方法进行遍历,将foreach语句中的obj声明为object类型进行遍历。
-------------方法一------------
键为:4;值为:星期四
键为:3;值为:星期三
键为:2;值为:星期二
键为:1;值为:星期一
-------------方法二------------
键为:4;值为:星期四
键为:3;值为:星期三
键为:2;值为:星期二
键为:1;值为:星期一
Hashtable元素的删除
编写程序,新建Hashtable的对象,向其中添加四个元素,然后进行删除。
Hashtable元素的查找
using System;
using System.Collections;
namespace Project8
{
class Program
{
static void Main(string[] args)
{
Hashtable ht = new Hashtable();
ht.Add("01", "星期一");
ht.Add("02", "星期二");
ht.Add("03", "星期三");
ht.Add("04", "星期四");
foreach (DictionaryEntry de in ht)
{
Console.WriteLine("键为{0};值为{1}",de.Key,de.Value);
}
Console.WriteLine("-------------Remove方法------------");
Console.WriteLine("移除哈希表中指定的键的元素");
ht.Remove("04");
foreach (DictionaryEntry de in ht)
{
Console.WriteLine("键为{0};值为{1}", de.Key, de.Value);
}
Console.WriteLine("\n-------------Clear方法------------");
Console.WriteLine("从 Hashtable 中移除所有的元素");
ht.Clear();
foreach (DictionaryEntry de in ht)
{
Console.WriteLine("键为{0};值为{1}", de.Key, de.Value);
}
Console.ReadKey();
}
}
}
【程序分析】本例演示了删除哈希表元素的两种方法。在代码中,首先创建对象ht,并添加四个元素;然后使用Remove方法,删除Hashtable中指定的键的元素;最后使用Clear方法,清除Hashtable中的所有元素。
键为02;值为星期二
键为03;值为星期三
键为04;值为星期四
键为01;值为星期一
-------------Remove方法------------
移除哈希表中指定的键的元素
键为02;值为星期二
键为03;值为星期三
键为01;值为星期一
-------------Clear方法------------
从 Hashtable 中移除所有的元素
Hashtable元素的查找
Hashtable中键与值成对存在,键是唯一的,不能重复查找元素的时候,用户往往是依据键去查找值的。
编写程序,新建Hashtable的对象,向其中添加四个元素,并查找键或值是否存在。
using System;
using System.Collections;
namespace Project9
{
class Program
{
static void Main(string[] args)
{
Hashtable ht = new Hashtable();
ht.Add(1, "星期一");
ht.Add(2, "星期二");
ht.Add(3, "星期三");
ht.Add(4, "星期四");
foreach (DictionaryEntry de in ht)
{
Console.WriteLine("键为{0};值为{1}", de.Key, de.Value);
}
Console.WriteLine("-------------ContainsKey------------");
Console.WriteLine("判断 Hashtable 是否包含的键:3");
if (ht.ContainsKey(3)) Console.WriteLine("存在该键");
else Console.WriteLine("不存该键");
Console.WriteLine("------------ContainsValue-----------");
Console.WriteLine("判断 Hashtable 是否包含的值:{0}",ht[1]);
if (ht.ContainsValue("星期一")) Console.WriteLine("存在改值");
else Console.WriteLine("不存该值");
Console.ReadKey();
}
}
}
【程序分析】本例演示了查找Hashtable中元素的两种方法。在代码中,首先创建对象ht,并添加四个元素;然后使用ContainsKey方法,判断键是否存在;再使用ContainsValue方法,判断值是否存在。
键为4;值为星期四
键为3;值为星期三
键为2;值为星期二
键为1;值为星期一
-------------ContainsKey------------
判断 Hashtable 是否包含的键:3
存在该键
------------ContainsValue-----------
判断 Hashtable 是否包含的值:星期一
存在改值