• 1. 《C#程序设计》 单元7 使用集合开发程序 主讲教师:C#课程组 授课专业:软件技术
  • 2. 单元7 使用集合开发程序 本章要点集合的概念和操作方法 泛型集合的应用方法技能目标能使用集合访问数据和操作数据 会使用泛型集合操作数据
  • 3. 单元7 使用集合开发程序
  • 4. 单元7 使用集合开发程序 7.2技术与知识准备 7.2.1集合
  • 5. 单元7 使用集合开发程序7.2.1.1集合概述 在前面我们学习了数组。数组是一组具有相同数据类型的数据的集合,在程序中可以用于存储数据。但是数组有一个缺点,即当其中的元素完成初始化后,要在程序中动态地给数组添加、删除某个元素是很困难的,存在着局限性。那么如何解决这个问题呢?.NET给我们提供了各种集合类,比如ArrayList和Hashtable,它们都位于System.Collections命名空间及其子命名空间中,都可以很好地进行元素的动态添加、删除操作。
  • 6. 单元7 使用集合开发程序7.2.1.2 ArrayList 1.给ArrayList添加数据 ArrayList通过Add方法添加元素。 语法: public int Add(object value) (1)含义:该方法将对象添加到ArrayList集合的末尾处。 (2)返回值:值是一个int整型,用于返回所添加的元素的索引。 (3)参数:如果向ArrayList中添加的元素是值类型,这些元素就都会被转换为object引用类型然后保存。所以ArrayList中的所有元素都是对象的引用。
  • 7. 单元7 使用集合开发程序2.访问ArrayList中的单个元素 ArrayList获取一个元素的方法和数组是一样的,也是通过索引(index)类访问,ArrayList中第一个元素的索引是0。需要注意的是,给ArrayList添加的元素都会被转换为Object型,所以在访问这些元素的时候必须把他们转换回原来的数据类型。 程序代码如下: private void button1_Click(object sender, EventArgs e) { TelNote note1=(TelNote)telNote[0]; TelNote note2=(TelNote)telNote[1]; MessageBox.Show(string.Format("{0}的电话是{1}", note1.Name,note1.Number)); }
  • 8. 单元7 使用集合开发程序3.遍历ArrayList中的元素 通过for循环或采用foreach方式遍历。 程序代码如下: //for循环遍历 for(int i=0;i
  • 9. 单元7 使用集合开发程序4.删除ArrayList中的元素 删除ArrayList的元素有以下三种方式。 语法: (1)通过RemoveAt(int index)方法删除指定index的元素。 (2)通过Remove(object value)方法删除一个指定对象名的元素。 (3)通过Clear( )方法移除集合中的所有元素 程序代码如下: private void button1_Click(object sender, EventArgs e) { //…… telNote.RemoveAt(0); telNote.Remove(tel3); MessageBox.Show(string.Format("电话本中共有{0}条记录", telNote.Count)); TelNote leave = (TelNote)telNote[0]; MessageBox.Show(string.Format("{0}的电话是{1}", leave.Name, leave.Number)); telNote.Clear(); MessageBox.Show(string.Format("电话本中共有{0}条记录", telNote.Count)); }
  • 10. 在ArrayList集合中我们使用索引访问它的元素,但是使用这种方式必须了解集合中某个数据的位置。当ArrayList中的元素变化频繁时,要跟踪某个元素的下标就比较困难了。C#中提供了一种叫Hashtable的数据结构,通常称为哈希表。哈希表的数据是通过键(Key)和值(Value)来组织的。键能唯一标识一个元素,通过键能访问其中的元素值。 1.给Hashtable添加数据 Hashtable的每个元素都是一个键/值对,给Hashtable添加一个对象,也要使用Add()方法。但哈希表的Add()方法有两个参数,一个表示键,一个表示键所对应的值。 语法: public void Add(object key,object value) 将电话本中的电话号码定为Key,电话本对象作为Value。添加三个电话记录的代码如下所示: telNote.Add(tel1.Number,tel1); telNote.Add(tel2.Number,tel2); telNote.Add(tel3.Number,tel3); 2.获取哈希表的元素 访问哈希表元素时,和ArrayList不同,可以直接通过键名来获取具体值。同样,由于值的类型是object,所以当得到一个值时也需要通过类型转换得到正确的类。如指定一个电话的Key值(电话号码)来获取它的对象,然后转换为TelNote类型,代码如下: TelNote note1=(TelNote)telNote[“81161234”];7.2.1.3 Hashtable 单元7 使用集合开发程序
  • 11. 3.删除哈希表的元素 语法: Public void Remove(object key) 通过key,使用Remove()方法删除哈希表的元素。 如:telNote.Remove(“81161234”); 我们看到,哈希表删除一个元素时使用的是它的Key值(电话号码),这样比较直观,也不会出现ArrayList使用索引删除时的问题。哈希表也可以使用Clear()方法清除所有元素,用法和ArrayList的情况相同,即telNote.Clear()。 4.遍历哈希表中的元素 由于哈希表不能够用索引访问,所以遍历一个哈希表只能用foreach()方法,代码如下所示。 //遍历Key foreach(object obj in telNote.Keys) { Console.WriteLine((string)obj); } //遍历value foreach(object obj in telNote.Values) { TelNote note=(TelNote)obj; Console.WriteLine(note.Name+”的电话号码是”+note.Number); } 分析:这里分别对telNote.Keys和telNote.Values遍历,而不是telNote对象本身。通常情况下,我们采用这种方式遍历Value和Key的值。 单元7 使用集合开发程序
  • 12. 通过ArrayList和Hashtable存储的数据类型都会被转换为Object类型,这意味着同一集合中可以加入不同类型的数据。但是在遍历集合的过程中就会出现异常,因为在对象转换时出错。 程序代码如下: ArrayList telNote = new ArrayList(); string address=”科教新城”; // 添加对象 telNote.Add(tel1); telNote.Add(tel2); telNote.Add(tel3); telNote.Add(address); //打印集合中元素的类型 MessageBox.Show(string.Format("电话本中共有{0}条记录?", telNote.Count)); //遍历 foreach(Object obj in telNote) { TelNote note=(TelNote)obj; Console.WriteLine(note.Name+”的电话号码是”+note.Number); }。 分析:向ArrayList集合中添加三个TelNote对象,一个字符串对象,这时程序正常,集合中有四个对象,但是遍历的过程中出现异常,因为在集合中保存了string对象,将它强制转换为TelNote对象,程序异常。7.2.2 泛型 7.2.2.1 泛型 单元7 使用集合开发程序
  • 13. 7.2.2.2 泛型集合List List类的用法非常类似于ArrayList,但是List有更大程度的类型安全性。定义一个List泛型集合的方法如下: 语法: List 对象名=new List(); “”中的T可以对集合中的元素类型进行约束,T表明集合中管理的元素类型。 修改代码如下: //通过索引访问 TelNote note=telNote[0]; //通过索引或者对象删除 telNote.RemoveAt(0); telNote.Remove(tel3); //打印集合数目 MessageBox.Show(string.Format("电话本中共有{0}条记录?", telNote.Count)); //遍历 foreach(TelNote item in telNote) { //遍历时无须类型转换 MessageBox.Show(string.Format("{0}的电话是{1}\n", item.Name,item.Number)); } 单元7 使用集合开发程序
  • 14. 在C#中还有一种泛型集合Dictionary,它具有泛型的全部特性,编译时检查类型约束,获取元素时无须类型转换,并且它存储数据的方式和哈希表类似,也是通过Key/Value(键/值对)保存元素的。 定义一个Dictionary泛型集合的方法如下所示。 语法: Dictionary 对象名=new Dictionary( ); 中的K表示集合中Key的类型,V表示Value的类型,它的含义和List是相同的。我们已经学习了哈希表的使用方法,所以对于Dictionary的使用,应该会很容易学习和掌握,部分代码如下所示: Dictionary telNote = new Dictionary(); TelNote tel1 = new TelNote(); tel1.Name = "范跑跑"; tel1.Number = "81161234"; TelNote tel2 = new TelNote(); tel2.Name = "郭美美"; tel2.Number = "62337878"; TelNote tel3 = new TelNote(); tel3.Name = "蔡跳跳"; tel3.Number = "56781112"; //添加元素 telNote.Add(tel1.Number,tel1); telNote.Add(tel2.Number, tel2); telNote.Add(tel3.Number, tel3);7.2.3泛型集合Dictionary 单元7 使用集合开发程序
  • 15. 通过7.2内容的学习,应该理解了集合和泛型的概念,能熟练使用各种泛型集合访问数据。下面我们将回到7.1中介绍的工作场景中,完成工作任务。7.3 回到工作场景 【步骤1】 1. 新建一个名为“SuperMarket”的Windows应用程序。 2.添加一个商品类(Goods),该类具有商品条形码(id)、商品名称(name)、商品价格(price)和商品数量(number)字段,属性Id、Name、Price、Number以及用于完成对象初始化工作的自定义构造函数。 【步骤2】 1.设计程序界面 单元7 使用集合开发程序
  • 16. 7.3回到工作场景 2.初始化库存商品集合信息。 Dictionary StockGoods; 3.窗体加载时,显示系统所有库存商品信息。 关键代码如下: //泛型集合StockGoods绑定ListView控件 private void FillList(Dictionary stockGoods,ListView listview) { lvGoods.Items.Clear(); if (StockGoods.Count == 0) { MessageBox.Show("没有数据", "注意", MessageBoxButtons.OK, MessageBoxIcon.Information); } else { foreach (Goods goods in StockGoods.Values) { string id = goods.Id; string name = goods.Name; string price = goods.Price.ToString(); string number = goods.Number.ToString(); string[] subItem = { id, name, price, number }; ListViewItem item = new ListViewItem(subItem); listview.Items.Add(item); } }单元7 使用集合开发程序
  • 17. 7.3 回到工作场景 【步骤3】实现商品信息的增加功能。 关键代码如下: //“添加”按钮的单击事件 private void btnAdd_Click(object sender, EventArgs e) { if (String.IsNullOrEmpty(txtID.Text) ||String.IsNullOrEmpty(txtName.Text) ||String.IsNullOrEmpty(txtPrice.Text) || String.IsNullOrEmpty(txtNumber.Text)) { MessageBox.Show("商品信息不能为空"); return; } Goods goods = new Goods(txtID.Text, txtName.Text, double.Parse(txtPrice.Text), int.Parse(txtNumber.Text)); StockGoods.Add(goods.Id,goods); FillList(StockGoods, lvGoods); } 单元7 使用集合开发程序
  • 18. 7.3回到工作场景 【步骤4】实现查看选定商品信息的功能。 关键代码如下: //“详细”按钮的单击事件 private void btnDetail_Click(object sender, EventArgs e) { if (this.lvGoods.SelectedItems.Count == 0) { MessageBox.Show("没有选择!"); return; } string key = this.lvGoods.SelectedItems[0].Text; this.txtID.Text = StockGoods[key].Id; this.txtName.Text = StockGoods[key].Name; this.txtPrice.Text = StockGoods[key].Price.ToString(); this.txtNumber.Text = StockGoods[key].Number.ToString(); }单元7 使用集合开发程序
  • 19. 7.3 回到工作场景 【步骤5】 实现删除选定商品信息的功能。 关键代码如下: //“删除”按钮的单击事件 private void btnDel_Click(object sender, EventArgs e) { if (this.lvGoods.SelectedItems.Count == 0) { MessageBox.Show("没有选择删除项!"); return; } string key = this.lvGoods.SelectedItems[0].Text; StockGoods.Remove(key); FillList(StockGoods,lvGoods); this.txtID.Text = ""; this.txtName.Text = ""; this.txtPrice.Text = ""; this.txtNumber.Text = ""; }单元7 使用集合开发程序
  • 20. 7.3 回到工作场景 【步骤6】 1.实现商品信息统计的功能。 private void btnTotal_Click(object sender, EventArgs e) { string count = string.Format("总共有{0}种商品信息!", StockGoods.Count.ToString()); MessageBox.Show(count); } 2.退出系统并释放资源。 private void btnExit_Click(object sender, EventArgs e) { this.Dispose(); }单元7 使用集合开发程序
  • 21. 7.4工作训练营 7.4.1项目训练 1、训练内容 编程在窗体中显示公司员工信息,并能根据员工工号进行“员工模糊查询”。设计应用程序,输入员工的工号显示相应员工信息 单元7 使用集合开发程序
  • 22. 2、训练目的 掌握泛型集合List的添加、查询操作,学会使用泛型集合绑定DataGridView控件。 3、训练过程 【步骤1】新建一个名为“Office”的Windows应用程序。 【步骤2】添加一个职工类Employee。类中有分别表示工号、姓名、年龄和性别的四个字段id、name、age和gender以及封装好的属性,其中gender为枚举类型;类中还有用于初始化员工对象的构造函数。 【步骤3】设计程序界面 单元7 使用集合开发程序
  • 23. 【步骤4】窗体加载时,显示系统所有员工信息。 关键代码如下: //初始化员工信息集合 List programmerList= new List(); //窗体加载方法实现泛型集合programmerList绑定DataGridView控件 private void Form1_Load(object sender, EventArgs e) { List programmerList = new List(); Employee jack = new Employee("001", "艾杰", 23, Gender.男); Employee joe = new Employee("002", "周欣", 25, Gender.女); Employee ema = new Employee("003", "黄龙", 24, Gender.男); programmerList.Add(jack); programmerList.Add(joe); programmerList.Add(ema); //用List绑定DataGridView的方法 dgvprogrammer.DataSource = new BindingList(programmerList); }单元7 使用集合开发程序
  • 24. 【步骤5】根据员工工号进行模糊。 关键代码如下: private void btnQuery_Click(object sender, EventArgs e) { //用临时列表保存查询到的信息 List tempList = new List(); foreach (Employee item in programmerList) { //用string类的IndexOf方法实现模糊查询逻辑 if (item.Id.IndexOf(txtID.Text.Trim()) != -1) { tempList.Add(item); } } dgvprogrammer.DataSource = new BindingList(tempList); } 4、技术要点 泛型集合List的添加、查询方法,泛型集合绑定DataGridView的方法。单元7 使用集合开发程序
  • 25. 7.4.2工作实践常见问题解析 【问题1】若List对象中的数据是不变的,如何用List绑定DataGridView? 【答】DataGridView 对象.DataSource=List 对象。 【问题2】如何用DataGridView显示字典集合数据? 【答】DataGridView显示字典集合数据,不能直接绑定。 方法如下: BindingSource bs=new BindingSource(); bs.DataSource=Dictionary 对象.Values; DataGridView 对象.DataSource=bs; 【问题3】集合中原来有三个对象,现在给集合再添加一个对象,其属性与集合中现有的一个元素的属性完全相同,用Remove()方法移除这个对象,这样是否会把两个属性值完全一样的对象一起删除呢? 【答】不会。通过Remove()方法移除集合中的元素一次只能移除一个,与被移除元素的属性完全相同的其他元素不受影响。 单元7 使用集合开发程序
  • 26. 小 结 ArrayList集合可以动态维护,访问元素时需要类型转换,ArrayList集合删除数据时,可以通过索引或者对象名访问其中的元素。 Hashtable类似于生活中的字典,它的元素都是以键/值对的形式存在。访问其中的元素需要进行类型转换,遍历Hashtable时,可以遍历其Value或Key;Hashtable不能通过索引访问,只能通过键访问值。 泛型集合可以约束它所存储的对象的类型,访问集合中的元素无须进行类型转换,List和ArrayList的用法相似,List访问元素无须进行类型转换,Dictionary和Hashtable的用法相似,Dictionary访问元素无须类型转换,泛型集合可以作为类的一个属性,使用泛型集合必须实例化。 本单元主要通过两个项目进行了集合、泛型的应用和操作,实现了项目化的集合训练,大家要再接再厉! 单元7 使用集合开发程序