【C#面向对象】第三课——使用集合保存数据、ArrayList集合、Hashtable集合的使用

    技术2022-07-10  137

    知识点:理解集合的概念、  掌握 ArrayList 集合的使用、  掌握 Hashtable 集合的使用、  掌握泛型集合的使用      

    1、集合简介

    通过对C#基础编程的学习,当我们需要保存多个相同类型的数据时,通常会使用数组,但是数组存在一些先天的不足: 长度固定,不能处理元素个数未知的情况。 执行一些特定操作不方便,如在数组中删除或插入元素时,需要编写大量代码实现。          所以现在主要主流的编程语言中,如 C#、Java 都提供了集合来组织数据,集合的长度可以动态维护,也就是可以保存任意数量的元素,同时提供了大量的方法可以对集合进行添加、删除、排序、复制等操作。  

    1.1 什么是集合

             集合(Collection)类是专门用于数据存储和检索的类。这些类提供了对栈(stack)、队列(queue)、列表(list)和哈希表(hash table)的支持。大多数集合类实现了相同的接口。            集合(Collection)类服务于不同的目的,如为元素动态分配内存,基于索引访问列表项等等。这些类创建 Object 类的对象的集合。在 C# 中,Object 类是所有数据类型的基类。            C#的集合类都保存在命名空间 System.Collections 下,主要有:         集合       说明                                                        描述和用法 动态数组 ArrayList 数组列表 它代表了可被单独索引的对象的有序集合。

    它基本上可以替代一个数组。但是,与数组不同的是,您可以使用索引在指定的位置添加和移除项目,动态数组会自动重新调整它的大小。它也允许在列表中进行动态内存分配、增加、搜索、排序各项。

    哈希表 Hashtable 键值对集合 它使用键来访问集合中的元素。

    当您使用键访问元素时,则使用哈希表,而且您可以识别一个有用的键值。哈希表中的每一项都有一个键/值对。键用于访问集合中的项目。

    队列 Queue 队列 它代表了一个先进先出的对象集合。

    当您需要对各项进行先进先出的访问时,则使用队列。当您在列表中添加一项,称为入队,当您从列表中移除一项时,称为出队。

    堆栈 Stack 它代表了一个后进先出的对象集合。

    当您需要对各项进行后进先出的访问时,则使用堆栈。当您在列表中添加一项,称为推入元素,当您从列表中移除一项时,称为弹出元素。

    排序列表 SortedList 排序列表集合 它可以使用键和索引来访问列表中的项。

    排序列表是数组和哈希表的组合。它包含一个可使用键或索引访问各项的列表。如果您使用索引访问各项,则它是一个动态数组(ArrayList),如果您使用键访问各项,则它是一个哈希表(Hashtable)。集合中的各项总是按键值排序。

    点阵列 BitArray 位值数组集合 它代表了一个使用值 1 和 0 来表示的二进制数组。

    当您需要存储位,但是事先不知道位数时,则使用点阵列。您可以使用整型索引从点阵列集合中访问各项,索引从零开始。

     

    2、 ArrayList(动态数组)

             ArrayList(动态数组)是一种类似于数组的集合,元素从前往后依次排列,通过索引 [n]来进行访问。ArrayList 的长度可以根据添加元素的个数自动扩充,删除或添加元素后索引会自动重新排列,提供了大量方法进行访问、添加、删除等操作。   ArrayList的使用步骤:  

    1)引入命名空间System.Collections

    2)创建实例。方法一:ArrayList arrayList = new ArrayList(); 方法二:ArrayList arrayList = new ArrayList(10);(括号中可以指定集合的初始容量,当超出该容量时会自动扩充,也可以不写,由系统决定。)

    3)引用对应的属性或方法

    ArrayList 主要的属性和方法有:                    属性                  说明 Count 元素个数 Capacity 集合容量                  方法                  说明 Add(Object value) 添加元素 Insert(int index,Object value) 插入元素 Remove(Object value) 删除元素 RemoveAt(int index) 通过索引删除元素 Clear() 清空所有元素

    2.1  ArrayList 添加元素

             ArrayList集合是C#中的一个非泛型的集合类,是弱数据类型的集合类,可以使用ArrayList集合变量来存储集合元素信息,任何数据类型的变量都可加入到同一个ArrayList集合中。 Add(object value):在 ArrayList 的末尾添加一个对象。AddRange(ICollection c):在 ArrayList 的末尾添加 ICollection 的元素(添加数组)。Insert( int index, object value ):在 ArrayList 的指定索引处,插入一个元素。    

    示例练习1:给ArrayList添加元素

    第一步,新建项目:在VS中新建控制台应用(.NET Framework),这里默认命名为【ConsoleApp3】,单击【确定】按钮,自动完成创建,并打开项目。

    第二步,编写代码:在主程序Main方法中,编写代码,声明一个动态数组,并指定初始容量是3。             ArrayList arrayList = new ArrayList(3);

    注意:第一行代码写好以后,程序提示错误,鼠标移上去以后有错误提示,因为我们没有添加引用,按照提示添加引用即可。   第三步,输出元素个数,预览效果:利用Count属性,输出元素个数, Console.WriteLine("arrayList初始化后,有{0}个元素",arrayList.Count); 然点击菜单栏【启动】,查看运行效果。可以先猜一下,有几个元素? 注意:虽然动态数组的初识容量指定为3,但是里面并没有添加元素,所以预览提示有0个元素。   第四步,使用Add方法添加元素:利用Add方法,添加元素。(任意类型都可以添加,因为把数据转换成了object类型,自动装箱操作)     第五步,使用AddRange方法添加元素:利用AddRange方法,添加多个元素。   第六步,使用Insert方法添加元素:利用Insert方法,添加元素。     第七步,使用foreach方法遍历元素:利用foreach方法,遍历ArrayList中的元素。   static void Main(string[] args) { //声明一个动态数组,并指定初始容量是3 ArrayList arrayList = new ArrayList(3); Console.WriteLine("arrayList初始化后,有{0}个元素",arrayList.Count);//Count属性,获取元素个数 //使用Add方法,向ArrayList中添加元素,每次只能添加一个元素 arrayList.Add(1024); arrayList.Add("hello"); arrayList.Add('a'); arrayList.Add(25.6); Console.WriteLine("使用Add方法添加4个元素之后,有{0}个元素", arrayList.Count); string[] stuStringArray = { "张三", "李四", "王五", "赵六" }; //声明一个string类型的数组,并存放数据 //AddRange方法,用于一次性向ArrayList中添加多个元素,可以是一个数组 arrayList.AddRange(stuStringArray); Console.WriteLine("使用AddRange方法添加数组之后,有{0}个元素", arrayList.Count); //使用Insert方法,向ArrayList中指定的索引位置,添加元素 arrayList.Insert(1, "我会出现在索引1的位置"); Console.WriteLine("使用Insert方法添加元素之后,有{0}个元素", arrayList.Count); //使用foreach方法,遍历ArrayList中的元素 foreach (object a in arrayList) { Console.Write(a+"\t"); } Console.ReadLine(); }

    案例总结:使用 Add 方法和AddRange方法将会把新元素添加到集合末尾,Insert 方法可以在集合任意位置插入新元素,所有加入集合的新元素都会被转换成 Object 类型,object类型是C#中所有数据类型的基类。

     

    示例练习2:给ArrayList中添加自定义类的对象

    第一步,新建项目:在VS中新建控制台应用(.NET Framework),这里默认命名为【ConsoleApp3.2】,单击【确定】按钮,自动完成创建,并打开项目。

    第二步,声明学生类:在Program.cs文件中,编写代码,声明一个学生类Student   第三步,声明教师类:在Program.cs文件法中,继续编写代码,声明一个教师类Teacher   第四步,new对象:在主程序Main方法中,new两个学生对象、一个教师对象。然后声明一个ArrayList集合,并将刚才new的对象添加到动态数组中     第五步,预览效果:点击菜单栏【启动】,查看运行效果。可以先猜一下,动态数组中有几个元素? 案例完整代码: namespace ConsoleApp3._2 { class Program { //声明一个学生类Student class Student { public string Name { get; set; } public float Score { get; set; } //声明一个方法,输出学生的分数 public void SayHello() { Console.WriteLine("大家好,我是学生:{0},我这次考了{1}分。",Name,Score); } } //声明一个教师类Teacher class Teacher { public string Name { get; set; } public string Subject { get; set; } //声明一个方法,输出教师的自我介绍 public void SayHello() { Console.WriteLine("大家好,我是{0}老师,我教的科目是:{1}。", Name, Subject); } } static void Main(string[] args) { //new第一个学生对象,并针对属性赋值 Student stu1 = new Student(); stu1.Name = "张三"; stu1.Score = 80.5f; //new第二个学生对象,并针对属性赋值 Student stu2= new Student(); stu2.Name = "李四"; stu2.Score = 90; //new一个教师对象,并针对属性赋值 Teacher teacher = new Teacher(); teacher.Name = "王迪"; teacher.Subject = "c#"; //声明一个动态数组,不指定容量 ArrayList arrayList = new ArrayList(); //向动态数组arrayList中添加对象 arrayList.Add(stu1); arrayList.Add(stu2); arrayList.Insert(0, teacher); //将对象teacher添加到集合中,索引位置是0 //输出动态数组中的元素个数,使用Count属性获取 Console.WriteLine("动态数组arrayList中,有{0}个元素",arrayList.Count); Console.ReadLine(); } } }

    案例思考:在这个案例中,我们将对象作为元素,添加到动态数组中。在初始化对象的时候,我们看到有三个对象,每个对象都要初始化并赋值,有没有更简单的方法可以实现?

       

    2.2  初始化器

             C#在 3.0 版本推出了新特性:初始化器,初始化器分为对象初始化器和集合初始化器,可以简化对象和集合的初始化代码。

    对象初始化器示例:类名 对象名 = new 类名(){属性1 = 属性值 , 属性2 = 属性值 , ……};

    //new一个学生对象,并针对属性赋值 Student stu1 = new Student(); stu1.Name = "张三"; stu1.Score = 80.5f; //使用对象初始化器,new一个学生对象,并初始化 Student stu2 = new Student() { Name = "张三", Score = 80 };//对象初始化器将创建对象和赋值合为一行,其中赋值就是在后面大括号里做的。这里的赋值可以给所有属性赋值,也可以给部分属性赋值。 Student stu3 = new Student { Name = "李四", Score = 90.5f };

    集合初始化器示例:ArrayList arrayList = new ArrayList() { 元素1 , 元素2 , ……};

    //声明一个动态数组ArrayList,并添加元素 ArrayList arrayList1 = new ArrayList(); arrayList1.Add(10); arrayList1.Add("hello"); arrayList1.Add(20.3); //使用集合初始化器,简化上面四行代码 ArrayList arrayList2 = new ArrayList { 10,"hello",20.3};//集合初始化器的原理也很简单,就是它默默的为我们调用了ArrayList的Add方法依次为我们添加了这3个元素。 ArrayList arrayList3 = new ArrayList() { 10, "hello", 20.3, 'a' };

    示例2中,第四步的操作(声明2个学生对象和1个教师对象,并将三个对象添加到动态数组中),可以使用集合初始化器,简化成以下写法:(注意符号不要缺少,记住初始语法即可)

    //使用集合初始化器,new三个对象初始化以后,添加到动态数组中 ArrayList arrayList = new ArrayList() { new Teacher(){ Name="王迪" , Subject="C#" }, new Student(){ Name="张三" , Score=80.5f }, new Student { Name="李四" , Score=90 } }; 代码说明:代码里用集合初始化器初始化了arrayList,然后用对象初始化器初始化了1个Teacher对象实例和2个Student对象实例。   总结:对象初始化器能对对象的公开属性进行初始化。而集合初始化器能在创建集合的同时,添加多个初始数据。        

    2.3  访问 ArrayList 的元素

             访问 ArrayList 元素和数组一样, 通过索引[n]来访问,要注意的是添加数据时,数据会转换为 Object类型保存起来,访问数据时必须进行类型转换。 static void Main(string[] args) { ArrayList arrayList = new ArrayList { 102,"hello",'a',2.5}; //使用索引访问arrayList集合中的元素,并输出 Console.WriteLine(arrayList[0]); //输出指定索引的元素 Console.WriteLine("arrayList集合中,索引1的元素是:{0}",arrayList[1]); Console.ReadLine(); }

    输出结果:

       

    示例练习3:访问ArrayList中的元素(在示例2的基础上修改)

    第一步,新建项目:在VS中新建控制台应用(.NET Framework),这里默认命名为【ConsoleApp3.3】,单击【确定】按钮,自动完成创建,并打开项目。

    第二步,编写代码:在将示例2中的代第二步和第三步完成,这里省略不写了。   第三步,访问元素:在主程序Main方法中,先使用初始化器向动态数组中添加三个元素,然后访问指定元素。 static void Main(string[] args) { //集合初始化器初始化了arrayList,然后用对象初始化器初始化了1个Teacher对象实例和2个Student对象实例 ArrayList arrayList = new ArrayList() { new Teacher(){ Name="王迪" ,Subject="C#" }, new Student(){ Name="张三" , Score=80.5f }, new Student { Name="李四" , Score=90 } }; //访问集合中的元素,并存储在对象中 Teacher teacher = (Teacher)arrayList[0];//将集合arrayList中索引0的元素,强制转换为Teacher类型 teacher.SayHello(); //调用对象的方法 Console.ReadLine(); }

     

    2.3  删除 ArrayList 的元素

             删除 ArrayList 元素的种方法:   Remove(Object value) 按对象删除:用于从 ArrayList 中移除特定对象的第一个匹配项  RemoveAt(int index) 按索引删除:用于移除 ArrayList 的指定索引处的元素  RemoveRange(int index, int count):从索引值开始,删除数量为count的数组  Clear() 全部删除

    代码练习:声明一个动态数组,添加元素后,依次使用四种方法进行删除练习

    static void Main(string[] args) { //使用集合初始化器,添加元素到动态数组中 ArrayList arrayList = new ArrayList { 11,0, "张三", 20.3, "张三",'a',5,6,7 }; Console.WriteLine("集合中的元素有:"); foreach(object a in arrayList) { Console.Write(a+"\t"); } Console.WriteLine(); //使用Remove方法删除 arrayList.Remove("张三"); Console.WriteLine("使用Remove方法删除后,集合中的元素有:"); foreach (object a in arrayList) { Console.Write(a + "\t"); } Console.WriteLine(); //使用RemoveAt方法删除 arrayList.RemoveAt(0); Console.WriteLine("使用RemoveAt方法删除后,集合中的元素有:"); foreach (object a in arrayList) { Console.Write(a + "\t"); } Console.WriteLine(); //使用RemoveRange方法删除 arrayList.RemoveRange(2,3); Console.WriteLine("使用RemoveRange方法删除后,集合中的元素有:"); foreach (object a in arrayList) { Console.Write(a + "\t"); } Console.WriteLine(); //使用Clear方法删除 arrayList.Clear(); Console.WriteLine("使用Clear方法删除后,集合中的元素有{0}个",arrayList.Count); Console.ReadLine(); }

    注意:删除集合中的元素之后,剩余元素的索引会重新排序。 

     

     

    2.4  遍历ArrayList

             遍历 ArrayList 和数组一样,可以使用 for 或 foreach 循环实现。要注意的是:如果集合中有不同类型的数据,进行类型转换前需要对类型进行判断,否则可能会报错。  

    示例练习4:遍历ArrayList中的元素(在示例2的基础上修改)

    第一步,新建项目:在VS中新建控制台应用(.NET Framework),这里默认命名为【ConsoleApp3.3】,单击【确定】按钮,自动完成创建,并打开项目。

    第二步,编写代码:在将示例2中的代第二步和第三步完成,这里省略不写了。   第三步,遍历元素:在主程序Main方法中,先使用初始化器向动态数组中添加三个元素,然后访问遍历输出元素。 static void Main(string[] args) { //使用集合初始化器,new三个对象初始化以后,添加到动态数组中 ArrayList arrayList = new ArrayList() { new Teacher(){ Name="王迪" ,Subject="C#" }, new Student(){ Name="张三" , Score=80.5f }, new Student { Name="李四" , Score=90 } }; //遍历输出集合中的元素,第一种方法:foreach方法 Console.WriteLine("使用foreach方法,遍历输出集合中的元素"); foreach (object item in arrayList) { if(item is Student) // 使用is关键字判断元素类型,这里判断元素是否Student类型,返回 true 或 false { Student stu = (Student)item; // 将元素强制转换为Student类型后,存储在对象stu里 stu.SayHello(); //调用对象的方法 } if(item is Teacher) { ((Teacher)item).SayHello(); //将两个步骤合并在一起 } } Console.WriteLine(); Console.WriteLine("使用for方法,遍历输出集合中的元素"); //遍历输出集合中的元素,第二种方法:for方法 for (int i = 0; i < arrayList.Count; i++) //使用Count属性,获取集合的索引长度(区别数组长度用的是Length属性) { if(arrayList[i] is Student) { ((Student)arrayList[i]).SayHello(); } if(arrayList[i] is Teacher) { ((Teacher)arrayList[i]).SayHello(); } } Console.ReadLine(); } }

       

    3、 Hashtable(哈希表)

            ArrayList 集合是通过索引来访问其中元素的,添加或删除元素后索引都会发生变化,再通过索引来访问元素存在一定困难。那么有没有更方便的方式来访问集合中的元素呢?我们可以给集合中元素加上名字,使用名字来访问元素,就像我们在班级里找人,只需要报上这人名字就可以了。 Hashtable 集合以键值对的形式组织数据,通过 key(关键字)来访问其中的 value(值)。 Hashtable 的结构:     Hashtable 的主要属性和方法:                      属性                      说明 Count 元素个数 Values 值的集合 Keys 键的集合                      方法                      说明 Add(Object key,Object value) 添加键和值 Remove(Object key) 通过键删除值 Clear() 清空集合 ContainsKey(Object key) 键是否存在

     

    3.1 Hashtable 添加元素

            Hashtable 的 Add 方法要同时添加键和值。我们可以用学生和老师的名字为键,对象为值。通过Hashtable 集合 [ ] 的方式来访问值,和 ArrayList 一样,获取的值需要进行类型转换。 注意: Hashtable 的键必须是唯一的,添加重复的键会出现异常。    

    示例练习5:给Hashtable添加元素

    第一步,新建项目:在VS中新建控制台应用(.NET Framework),这里默认命名为【ConsoleApp3.4】,单击【确定】按钮,自动完成创建,并打开项目。

    第二步,声明学生类:在Program.cs文件中,编写代码,声明一个学生类Student

     

    第三步,声明Hashtable对象:在主程序Main方法中,编写代码,声明一个Hashtable对象(注意引入命名空间using System.Collections;)

     

    第四步,添加元素到Hashtable里:在主程序Main方法中,继续编写代码,声明两个Student对象,将他们添加到hashtable里 Hashtable在存储数据的时候,可以参照下图:   第五步,读取Hashtable的元素:取出需要的元素,进行输出。   预览效果:   完整代码: namespace ConsoleApp3._4 { //声明一个学生类Student class Student { public string Name { get; set; } public float Score { get; set; } public string Id { get; set; } //声明一个方法,输出学生的分数 public void SayHello() { Console.WriteLine("大家好,我是学生:{0},学号是{1},我这次考了{2}分。", Name, Id,Score); } } class Program { static void Main(string[] args) { //声明一个Hashtable对象 Hashtable hashtable = new Hashtable(); //初次使用,注意引入命名空间using System.Collections; //声明两个Student对象 Student stu1 = new Student { Name = "张三", Score = 82, Id = "1001" }; Student stu2 = new Student { Name = "李四", Score = 90.5f,Id="1002" }; //将上一步声明的两个student对象,添加到hashtable里(装箱操作) hashtable.Add(stu1.Id, stu1); //Add方法里,stu1.Id是键,stu1是值 hashtable.Add(stu2.Id, stu2); //取出hashtable里的数据(拆箱操作),通过键取对应的元素 Student student = (Student)hashtable["1001"]; //调用student对象的方法 student.SayHello(); ((Student)hashtable["1002"]).SayHello(); //将上面两行代码简化 Console.ReadLine(); } } }

    案例思考:如何修改元素?如,将第二个学生对象的姓名,修改为“王迪”。关键代码:((Student)hashtable["1002"]).Name = "王迪";

       

    3.2   删除 Hashtable 的元素

    删除 Hashtable 的元素有两种方式:   Remove(Object key)   Clear()            删除某一个元素很简单,只用填写该元素的 key,示例: hashtable.Remove(" 1001"); 如果该 key 存在将会删除该对象,否则不会有任何效果。 key 是否存在可以通过 Hashtable 的方法 ContainsKey(Object key) 来判断。    

    示例练习6:查找和删除Hashtable中的元素(在示例5的基础上继续练习)

    关键代码:在Main方法中,继续输入以下代码进行练习

    //查找是否存在某个元素,可以通过ContainsKey()方法和ContainsValue()方法,返回true或false Console.WriteLine(hashtable.ContainsKey("1003")); Console.WriteLine(hashtable.ContainsValue(stu1)); //使用Remove()方法,删除指定键值的元素 hashtable.Remove("1002"); Console.WriteLine("hashtable元素中共有{0}个元素",hashtable.Count); //使用Count属性,获取元素个数 //使用Clear()方法,删除全部元素 hashtable.Clear();

    案例思考:Console.WriteLine(hashtable.ContainsValue("张三"));  将会输出true还是false?为什么?

       

    3.2   遍历 Hashtable

            Hashtable 的结构由 key-value 对组成,遍历方法和 ArrayList 不太一样,我们可以对 key value 分开遍历。  

    示例练习7:遍历Hashtable中的元素(在示例5的基础上修改)

    第一步,新建项目:在VS中新建控制台应用(.NET Framework),这里默认命名为【ConsoleApp3.5】,单击【确定】按钮,自动完成创建,并打开项目。

    第二步,编写代码:在将示例5中的代第二步到第四步完成,这里省略不写了。(可以直接将相关代码复制过去)   第三步,遍历元素:在主程序Main方法中,遍历输出元素。(有三种使用情况)   预览效果:   关键代码:   //遍历hashtable里的数据 Console.WriteLine("1、遍历hashtable里的key"); foreach (object obj in hashtable.Keys) //遍历hashtable里的key { Console.WriteLine(obj); } Console.WriteLine("\n2、遍历hashtable里的Values"); foreach (object obj in hashtable.Values) //遍历hashtable里的Values { Student stu = (Student)obj; stu.SayHello(); } Console.WriteLine("\n3、同时遍历hashtable里的key和Value"); foreach (DictionaryEntry entry in hashtable) //遍历hashtable里的Values { Console.WriteLine(entry.Key); Student stu = (Student)entry.Value; stu.SayHello(); }

    代码分析:DictionaryEntry 可以看作是一个完整的 key-value 对。Hashtable 由多个 DictionaryEntry 组成。

       

    4、 泛型集合

              前面我们对 ArrayList 集合和Hashtable集合进行遍历时,因为集合中存在不同类型的对象,在类型转换时存在出错的风险,同时类型转换降低了程序性能。           在 C#2.0 版添加了新特性:泛型,泛型引入了类型参数( Type Parameters)的概念,通过定义类型参数(T),限定了集合、类、方法处理的具体类型,从而降低类型转换错误的风险,也提高了程序运行的性能。泛型最常见的就是集合。List<T>集合添加和删除的方法和 ArrayList 完全相同,在访问和遍历集合时不需要进行类型转换    

    4.1   List<T>

              泛型集合保存在命名空间 System.Collections.Generic 中,前面学习的 ArrayList Hashtable 都可以用泛型集合代替。           List<T>集合和 ArrayList 用法类似,创建 List<T>集合的方法: List<T>  list = new List<T>();           <T>中的 T 代表具体的类型,如: Student Teacher 这些自定义的类,也可以是 int string 等基本数据类型。规定了类型后集合中将只能保存该类型的数据。    

    示例练习8:使用List集合

    第一步,新建项目:在VS中新建控制台应用(.NET Framework),这里默认命名为【ConsoleApp3.6】,单击【确定】按钮,自动完成创建,并打开项目。

    第二步,声明学生类:在命名空间里声明一个学生类,关键代码如下:(也可以直接复制前面示例练习的代码) //声明一个学生类Student class Student { public string Name { get; set; } public float Score { get; set; } //声明一个方法,输出学生的分数 public void SayHello() { Console.WriteLine("大家好,我是学生:{0},我这次考了{1}分。", Name, Score); } }

    第三步,使用List集合:在主程序Main方法中,声明List集合,并进行添加元素、访问元素、遍历元素的操作。

    预览效果:

    关键代码:

    static void Main(string[] args) { //声明一个List集合 List<Student> list = new List<Student>(); // 指定list集合中的数据类型是Student类型 //声明两个Student对象 Student stu1 = new Student() { Name = "张三", Score = 80 }; Student stu2 = new Student() { Name = "李四", Score = 90 }; //将声明的两个Student对象,stu1和stu2,添加到list集合里 list.Add(stu1); list.Add(stu2); //访问数据 list[0].SayHello(); //使用索引访问 //遍历集合中的元素 Console.WriteLine("\n遍历list集合中的元素"); for(int i=0; i < list.Count; i++) { list[i].SayHello(); } Console.ReadLine(); }

    案例思考:

    1)如何使用初始化器,简化上面的代码?

    2)如果添加这行代码,会怎样?list.Add(10);  

    3)如何修改集合中的元素?如将李四的分数,修改为70.

    4)如何删除集合中的元素?

    5)如何查找集合中是否包含某个元素?

     

    4.2   Dictionary<K,V>

               和 Hashtable 用法类似的泛型集合是 Dictionary<K,V> Dictionary(字典)也是通过键值对保存数据的集合,定义时要指定 K key )和 V value)两个类型。 定义 Dictionary<K,V>的语法: Dictionary<K,V> dictionary = new Dictionary<K,V>();    

    示例练习9:使用Dictionary集合

    第一步,新建项目:在VS中新建控制台应用(.NET Framework),这里默认命名为【ConsoleApp3.7】,单击【确定】按钮,自动完成创建,并打开项目。

    第二步,声明学生类:在命名空间里声明一个学生类,关键代码如下:(也可以直接复制前面示例练习的代码) //声明一个学生类Student class Student { public string Name { get; set; } public float Score { get; set; } //声明一个方法,输出学生的分数 public void SayHello() { Console.WriteLine("大家好,我是学生:{0},我这次考了{1}分。", Name, Score); } }

    第三步,使用Dictionary集合:在主程序Main方法中,声明List集合,并进行添加元素、访问元素、遍历元素的操作。

      预览效果:   关键代码: static void Main(string[] args) { //声明一个Dictionary集合 Dictionary<string, Student> dictionary = new Dictionary<string, Student>(); //键是string类型,值是Student类型 //声明两个Student对象 Student stu1 = new Student() { Name = "张三", Score = 80 }; Student stu2 = new Student() { Name = "李四", Score = 90 }; //将声明的两个Student对象,stu1和stu2,添加到dictionary集合里 dictionary.Add("张三", stu1); dictionary.Add("李四", stu2); //访问数据 Console.WriteLine(dictionary["张三"].Name); //使用键访问元素,并取出Name属性 //遍历集合中的元素 Console.WriteLine("\n通过values,遍历dictionary集合中的元素"); foreach(Student stu in dictionary.Values) { stu.SayHello(); } Console.WriteLine("\n通过keys,遍历dictionary集合中的元素"); foreach (string str in dictionary.Keys) //因为前面声明dictionary元素的时候,key是string类型 { Console.WriteLine(str); } Console.WriteLine("\n通过KeyValuePair<k,v>,遍历dictionary集合中的元素"); foreach (KeyValuePair<string,Student> item in dictionary) { Console.WriteLine(item.Key); (item.Value).SayHello(); } Console.ReadLine(); }         总体上 List<T> ArrayList Dictionary<K,V> Hashtable 添加、删除、访问元素和遍历的方法都是相同的,不同的是:在添加数据时有严格的类型检查,在访问和遍历时不需要做类型转换。

    泛型集合的优点:

     性能高,省去了在装箱、拆箱上的性能损耗。  类型安全,保证了集合中都是同一类型的数据。  代码重用,将类型作为参数,不需要为特定类型编写单独的代码,极大提高了重用性。      

    4.3  使用泛型接口

             泛型不止应用于集合,还有泛型类、泛型接口、泛型方法等,随着学习的深入大家都会接触到。List 集合排序的方法是 Sort(IComparer<T> ) ,参数 IComparer<T> 是泛型接口,用于指定两个元素间如何比较。    

    示例练习10:使用Dictionary集合

    第一步,新建项目:在VS中新建控制台应用(.NET Framework),这里默认命名为【ConsoleApp3.8】,单击【确定】按钮,自动完成创建,并打开项目。

    第二步,声明学生类:在命名空间里声明一个学生类,关键代码如下:(也可以直接复制前面示例练习的代码)   第三步,自定义分数比较器类:在命名空间里声明一个类,关键代码如下   第四步,使用list集存元素,排序后输出:在主程序Main方法中,声明List集合,并添加数据,进行排序,遍历输出 预览效果:   关键代码: namespace ConsoleApp3._8 { //声明一个学生类 class Student { public string Name { get; set; } public float Score { get; set; } public void SayHello() { Console.WriteLine("大家好,我是学生{0},这次考了{1}分", Name, Score); } } //自定义分数比较器 class ScoreComparer : IComparer<Student> { public int Compare(Student x, Student y) { return x.Score.CompareTo(y.Score); } } class Program { static void Main(string[] args) { //使用List<T> List<Student> list = new List<Student>() { new Student() { Name = "jack", Score = 80 }, new Student() { Name = "may", Score = 89 }, new Student() { Name = "jhon", Score = 66 } }; //按分数排序 list.Sort(new ScoreComparer()); //遍历排序后的集合 foreach(Student stu in list) { stu.SayHello(); } Console.ReadLine(); } } }

    案例延伸:示例中 ScoreComparer 类实现了 IComparer<T>接口的 CompareTo 方法,指定按分数排序,默认情况下是升序,如果要降序排序,交换方法体中 x y 的位置就可以了,调用 List 集合的 Sort 方法时,传递该类的对象,集合就知道如何进行排序了。

       

    本课总结

      集合的长度可以动态维护,同时提供了大量的方法可以对集合进行添加、删除、排序、复制等操作。   ArrayList(数组列表)是一种类似于数组的集合,元素从前往后依次排列,通过索引[n]来进行访问。ArrayList 的长度可以根据添加元素的个数自动扩充,删除或添加元素后索引会自动重新排列,提供了大量方法进行访问、添加、删除等操作。   Hashtable 集合以键值对的形式组织数据,通过 key(关键字)来访问其中的 value(值)。   List<T>ArrayListDictionary<K,V>Hashtable 添加、删除、访问元素和遍历的方法都是相同的,不同的是:在添加数据时有严格的类型检查,在访问和遍历时不需要做类型转换。   泛型集合的优点: 性能高,省去了在装箱、拆箱上的性能损耗。 类型安全,保证了集合中都是同一类型的数据。 代码重用,将类型作为参数,不需要为特定类型编写单独的代码,极大提高了重用性。   泛型不止应用于集合,还有泛型类、泛型接口、泛型方法等,IComparer<T>是比较器泛型接口。           ================这里是结束分割线================
    Processed: 0.018, SQL: 9