1.1 集合概述
3.1.1 集合的主要特征与类型
- 在.NET 平台封装好了一些常用的数据结构,称为集合类,简称“集合”
- C# 中的集合表示可以通过遍历方式来访问一组对象,其主要特性如下
- 动态地改变大小
- 可存储任意类型的对象
- 提供一系列操作集合中对象的方法
- C# 中的集合被定义在 System.Collections 命名空间中,如图 3.1 所示,如 ArrayList(数组列表)、Hashtable(字典)、Queue(队列)、Stack(栈)和 SortedList(排序列表)等
3.1.2 数组的缺陷
客户在银行办理业务时,常常需要排队,现在我们定义一个数组来保存排队等候办理业务的客户
示例:
public class Customer//定义客户类
{
private string name; // 姓名
private int age; // 年龄
private string address; // 住址
//省略构造方法及属性的封装…
}
static void Main(string[] args)
{
Customer[] list = new Customer[2];//保护排队客户
Customer teng = new Customer(" 马腾 ", 32, " 汕头市 ");
Customer yun = new Customer(" 王云 ", 28, " 杭州市 ");
list[0] = teng;
list[1] = yun;
Console.WriteLine(" 排队等待的客户有:");
for (int i = 0; i < list.Length; i++)
{
Console.WriteLine("{0} 号:{1}", i+1, list[i].Name);
}
}
思考:
我们在示例 3.1 的留白处添加下述代码: Customer jun = new Customer(" 李军 ", 25, " 仙桃市 "); list[2] = jun; 添加了此段代码后,运行结果将是什么?
3.2 列表集合 ArrayList
3.2.1 ArrayList介绍
- ArrayList 类似于数组,因其大小可根据需要动态地改变,故也可称为动态数组
- ArrayList 把所有存储的元素都当作对象引用,因而可以在 ArrayList 中存储任何对象,但在访问对象时,需要把它们的数据类型转换回存储前的类型
3.2.2 ArrayList的使用
使用ArrayList类实现3.1的功能
示例:
static void Main(string[] args)
{
ArrayList list = new ArrayList() { };//使用ArrayList集合代替数组
Customer teng = new Customer(" 马腾 ", 32, " 汕头市 ");
Customer yun = new Customer(" 王云 ", 28, " 杭州市 ");
Customer si= new Customer(" 李军 ", 25, " 仙桃市 ");
list.Add(teng);
list.Add(yun);
list.Add(si);
Console.WriteLine(" 排队等待的客户有:");
for (int i = 0; i < list.Count; i++)
{
Console.WriteLine("{0} 号:{1}", i+1, (list[i] as Customer).Name);
}
}
注意:
- 当有新的客户需要排队时,可以继续添加
- 任何对象存储到 ArrayList 中都会自动转换成 object 类型的数据,所以在访问时必须从 object 类型转换回存储前的类型。
- ArrayList 的常用属性
- Capacity :获取或设置 ArrayList 可包含的元素个数
- Count :获取 ArrayList 实际包含的元素个数
下面将以用户的添加为例,说明 Capacity 和 Count 的用法
示例:
static void Main(string[] args)
{
Customer jun = new Customer(" 李军 ",32," 广州 "); // 创建客户 1
Customer yun = new Customer(" 王云 ", 28, " 杭州 "); // 创建客户 2
Customer si = new Customer(" 雷斯 ", 43, " 美国 "); // 创建客户 3
ArrayList list = new ArrayList(2); //创建时可以指定容量
Console.WriteLine(" 集合可存储元素数:{0}", list.Capacity);
Console.WriteLine(" 集合实际元素数:{0}", list.Count);
list.Add(jun);
Console.WriteLine(" 集合可存储元素数:{0}", list.Capacity);
Console.WriteLine(" 集合实际元素数:{0}", list.Count);
list.Add(yun);
list.Add(si);
Console.WriteLine(" 集合可存储元素数:{0}", list.Capacity);
Console.WriteLine(" 集合实际元素数:{0}", list.Count);
}
ArrayList的常用方法
- Add(object obj) :将元素添加到 ArrayList 结尾处
- Insert(int index,object obj) :将元素添加到 ArrayList 的指定索引处
- Remove(object obj) :移除 ArrayList 指定的元素
- RemoveAt(int index) :移除 ArrayList 指定索引处元素
- Clear() :清除 ArrayList 中所有元素
- Sort() :对 ArrayList 中的元素排序
- Reverse() :将 ArrayList 中的元素顺序反转
- TrimToSize() :将 ArrayList 容量数设置为实际元素个数
使用ArrayList集合添加元素
示例:
static void Main(string[] args){
int num = 1;
Customer jun = new Customer(" 李军 ",32," 广州 ");
Customer yun = new Customer(" 王云 ", 28, " 杭州 ");
Customer si = new Customer(" 雷斯 ", 43, " 美国 ");
ArrayList list = new ArrayList(2);
list.Add(jun);
list.Add(yun);
list.Insert(1, si);
Console.WriteLine(" 排队的客户有:");
foreach (object obj in list)
{
Customer cust = obj as Customer;
Console.WriteLine("{0} 号客户:{1}", num++, cust.Name);
}
}
使用ArrayList集合访问元素
示例:
static void Main(string[] args)
{
Customer jun = new Customer(" 李军 ",32," 广州 ");
Customer yun = new Customer(" 王云 ", 28, " 杭州 ");
Customer si = new Customer(" 雷斯 ", 43, " 美国 ");
ArrayList list = new ArrayList(2);
list.Add(jun);
list.Add(yun);
list.Add(si);
Customer cust = list[1] as Customer;
Console.WriteLine("2 号客户:{0}", cust.Name);
}
根据索引,使用ArrayList集合删除元素
示例:
static void Main(string[] args)
{
int num =1;//排队序号
//初始化客户代码省略…
ArrayList list = new ArrayList(2);
list.Add(jun);
list.Add(yun);
list.Add(si);
list.RemoveAt(0);
Console.WriteLine(" 排队的客户有:");
foreach (object obj in list)
{
Customer cust = obj as Customer;
Console.WriteLine("{0} 号客户:{1}", num++, cust.Name);
}
}
使用ArrayList集合通过 Sort() 和 Reverse() 方法进行排序
示例:
static void Main(string[] args)
{
//初始化客户代码省略…
num = 1;
list.Sort();//使用sort方法进行排序
Console.WriteLine(" 使用 Sort() 方法排序后:");
foreach (string cust in list)
{
Console.WriteLine("{0} 号客户:{1}", num++, cust);
}
num = 1;
list.Reverse();
Console.WriteLine(" 使用 Reverse() 方法排序后:");
//循环输出客户代码省略…
}
3.3 字典集合 Hashtable
3.3.1 ArrayList的局限性
- Hashtable 是用于处理 key/value( 键 / 值 ) 对的集合容器
- key 通常用于快速查找,value 用于存储对应于 key 的值,key 区分大小写。Hashtable 中键值均为 object 类型
3.3.2 Hashtable的使用
在ArrayList集合中找到指定元素
示例:
static void Main(string[] args)
{
//初始化客户代码省略…
string name = " 王云 "; //需要查找的客户姓名
for(int i=0;i<list.Count;i++)//查找姓名为王云的客户是否在排队,如果找到则显示其住址
{
Customer cust = list[i] as Customer;
if (cust.Name.Equals(name))
{
Console.WriteLine("{0} 客户在排队,其住址是:{1}", name, cust.Address);
break;
}
}
}
使用Hashtable实现上述案例
static void Main(string[] args)
{
Customer jun = new Customer(" 李军 ",32," 广州 ");
Customer yun = new Customer(" 王云 ", 28, " 杭州 ");
Customer si = new Customer(" 雷斯 ", 43, " 美国 ");
Hashtable list = new Hashtable();
list.Add(jun.Name, jun);
list.Add(yun.Name, yun);//把客户的姓名存为 key,客户对象存为 value
list.Add(si.Name, si); string name = " 王云 ";
Customer cust = list[name] as Customer;
Console.WriteLine("{0} 客户在排队,其住址是:{1}", name, cust.Address);
}
Hashtable 的 key 和 value 都是 object 类型的,所以在访问时必须从 object 类型转换回存储前的类型。
Hashtable的常用属性见下表
- Keys :获取包含 Hashtable 中所有键的 ICollection
- Values :获取包含 Hashtable 中所有值的 ICollection
- Count :获取 Hashtable 中键/值对的数目
C# 支持 foreach 关键字,foreach 循环在处理集合和数组相对于 for 循环存在以下 4 个优势
- foreach 语句简洁
- foreach 循环效率比 for 循环要高
- 不用关心数组的起始索引是什么
- 处理多维数组更加方便
语法:
foreach(Type t in arrays)
{
//..do your things
}
Type: 需要遍历每一个对象的类型
arrays: 需要遍历的对象
t: 每一个对象
使用 foreach 循环遍历 Hashtable
示例:
static void Main(string[] args)
{
//初始化Hashtable语句省略……
Console.WriteLine("list 包含以下键:");
//遍历 Hashtable 中所有键对象
foreach (object key in list.Keys)
{
Console.WriteLine(key);
}
Console.WriteLine("list 包含以下值:");
//遍历 Hashtable 中所有值对象
foreach (object value in list.Values)
{
Customer cust = value as Customer;
Console.WriteLine(" 姓名:{0},年龄:{1},住址:{2}", cust.Name, cust.Age, cust.Address);
}
Console.WriteLine("list 中键值对的个数:{0}", list.Count);
}
Hashtable的常用方法
- Add(object key, object value) :将带有指定键和值的元素添加到 Hashtable 中
- Remove(object key):从 Hashtable 中移除带有指定键的元素
- Clear() :移除 Hashtable 中所有元素
- ContainsKey(object key):确定 Hashtable 中是否包含指定键
- ContainsValue(object value) :确定 Hashtable 中是否包含指定值
删除Hashtable中的元素
示例:
static void Main(string[] args)
{
Customer jun = new Customer(" 李军 ",32," 广州 ");
Customer yun = new Customer(" 王云 ", 28, " 杭州 ");
Customer si = new Customer(" 雷斯 ", 43, " 美国 ");
Hashtable list = new Hashtable();
list.Add(jun.Name, jun);
list.Add(yun.Name, yun);
list.Add(si.Name, si);
list.Remove(yun.Name); //通过 key 来删除集合中的元素
foreach (object value in list.Values)
{
Customer cust = value as Customer;
Console.WriteLine(" 姓名:{0},年龄:{1},住址:{2}", cust.Name, cust.Age, cust.Address);
}
}
访问Hashtable中的指定元素
示例:
static void Main(string[] args)
{
//初始化Hashtable语句省略……
string name = " 李宏 ";
if (list.ContainsKey(name)) //判断是否有键为name的元素
{
Customer cust = list[name] as Customer;
Console.WriteLine("{0} 客户在排队,其住址是:{1}", name, cust.Address);
}
else
{
Console.WriteLine("{0} 客户没有排队。", name);
}
}
、
总结:
1、C#中集合的主要特性
- 动态改变大小
- 可存储任意类型的对象
- 提供一系列操作集合中对象的方法
2、任何对象存储到ArrayList集合中都会自动转换成object类型的数据,在访问时必须从object转换回存储前的类型
3、ArrayList中存储的元素超出容量时,其容量自动增长一倍
4、Hashtable是用于处理key/value(键/值)对的集合容器,其中key通常用于快速查找,value用于存储对应于key的值。 key和value都是object类型