它基本上可以替代一个数组。但是,与数组不同的是,您可以使用索引在指定的位置添加和移除项目,动态数组会自动重新调整它的大小。它也允许在列表中进行动态内存分配、增加、搜索、排序各项。
哈希表 Hashtable 键值对集合 它使用键来访问集合中的元素。当您使用键访问元素时,则使用哈希表,而且您可以识别一个有用的键值。哈希表中的每一项都有一个键/值对。键用于访问集合中的项目。
队列 Queue 队列 它代表了一个先进先出的对象集合。当您需要对各项进行先进先出的访问时,则使用队列。当您在列表中添加一项,称为入队,当您从列表中移除一项时,称为出队。
堆栈 Stack 栈 它代表了一个后进先出的对象集合。当您需要对各项进行后进先出的访问时,则使用堆栈。当您在列表中添加一项,称为推入元素,当您从列表中移除一项时,称为弹出元素。
排序列表 SortedList 排序列表集合 它可以使用键和索引来访问列表中的项。排序列表是数组和哈希表的组合。它包含一个可使用键或索引访问各项的列表。如果您使用索引访问各项,则它是一个动态数组(ArrayList),如果您使用键访问各项,则它是一个哈希表(Hashtable)。集合中的各项总是按键值排序。
点阵列 BitArray 位值数组集合 它代表了一个使用值 1 和 0 来表示的二进制数组。当您需要存储位,但是事先不知道位数时,则使用点阵列。您可以使用整型索引从点阵列集合中访问各项,索引从零开始。
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() 清空所有元素第一步,新建项目:在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#中所有数据类型的基类。
第一步,新建项目:在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(); } } }案例思考:在这个案例中,我们将对象作为元素,添加到动态数组中。在初始化对象的时候,我们看到有三个对象,每个对象都要初始化并赋值,有没有更简单的方法可以实现?
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对象实例。 总结:对象初始化器能对对象的公开属性进行初始化。而集合初始化器能在创建集合的同时,添加多个初始数据。输出结果:
第一步,新建项目:在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(); }
注意:删除集合中的元素之后,剩余元素的索引会重新排序。
第一步,新建项目:在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(); } }第一步,新建项目:在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 = "王迪";
关键代码:在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?为什么?
第一步,新建项目:在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 组成。
第一步,新建项目:在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)如何查找集合中是否包含某个元素?
第一步,新建项目:在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 添加、删除、访问元素和遍历的方法都是相同的,不同的是:在添加数据时有严格的类型检查,在访问和遍历时不需要做类型转换。第一步,新建项目:在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 方法时,传递该类的对象,集合就知道如何进行排序了。