C# 用集合组织相关数据
Harde原创于harde.org转载请注明
集合ArrayList和数组是十分相似的,事实上很多人称之为数组列表,
但是他们的区别也是很明显的,ArrayList可以非常直观地动态维护
比如说如果你定义了一个数组string [] test = new string[10];如果你想要再扩展容量,你只有使用Array.Resize(ref T[] array,int newSize);来扩张容量,而ArrayList就没有那么麻烦,因为它是动态的,因而在定义时既可以指定容量也可以不指定。
有一点要注意ArrayList是来自于System.Collections的,因此在使用前记得添加using System.Collections;。下面我来定义一个ArrayList
using System.Collections;
ArrayList Test = new ArrayList();
这就定义了一个ArrayList向ArrayList中添加元素很简单,只需要调用Add(Object value)即可
注意看这里是Object类型,因此当添加的元素为值类型的,会被转换为object引用类型后保存,所以ArrayList中所有的元素都是对象的引用。(Add()方法会返回一个int值,代表了刚才添加元素的索引)
请看示例
private void btnMyClassTest_Click(object sender, EventArgs e) { //建立班级学员的集合 ArrayList Students = new ArrayList(); Student scofield = new Student("Scofield", Genders.Male, 28, "越狱狱"); Student zhang = new Student("张靓靓", Genders.Female, 20, "唱歌歌"); Student jay = new Student("周杰杰", Genders.Male, 21, "耍双节棍棍"); Students.Add(scofield); Students.Add(zhang); Students.Add(jay); //打印集合数目 MessageBox.Show(string.Format("共包括{0} 个学员。", Students.Count.ToString())); }
好了,会了添加让我们再来看下
存取单个元素
在数组中我们都是通过索引下标来访问元素的,ArrayList也不例外
但是有一点要注意
因为所有数据在ArrayList中都是以object类型存放的
因此再取的时候要转换成原来的数据类型
请看以下代码
Student stu1 = (Student)Students[0]; stu1.SayHi();
这段代码就会调用出scofield的学员资料
好了,会了存取下面我们得看下删除了,删除ArrayList中的数据也很简单
使用
ArrayList.Remove(对象名) //删除指定对象名的对象 ArrayList.RemoveAt(index) //删除指定索引的对象 ArrayList.Clear() //清除集合内的所有元素
这三个方法就可以
比如Students.RemoveAt(0);就会删除scofield的资料,(同样我们也可以这样删除ArrayList.Remove(scofield))
说道数组,就不得不提下“遍历”
在日常使用中“遍历是我们经常用到的东西,通常对于数组,我们都是用for循环语句来遍历的,同样的ArrayList也不例外,另外ArrayList还可以使用foreach来遍历
代码:
for (int i = 0; i < Students.Count; i++) { Student stuFor = (Student)Students[i]; Console.WriteLine(stuFor.Name); } [/csharp] 再来看看用foreach遍历 [csharp ] foreach (Object stuo in Students) { Student stuForeach = (Student)stuo; Console.WriteLine(stuForeach.Name); } [/csharp] 这两种方法效果是一样的 但是有点区别,for是通过索引来访问元素,而foreach是通过对象来访问的。 常见错误 请问这样写对么? [csharp ] Student scofield = new Student("Scofield", Genders.Male, 28, "越狱狱"); Student zhang = new Student("张靓靓", Genders.Female, 20, "唱歌歌"); Student jay = new Student("周杰杰", Genders.Male, 21, "耍双节棍棍"); students.Add(scofield); students.Add(zhang); students.Add(jay); students.RemoveAt(0); students.RemoveAt(1); students.RemoveAt(2); [/csharp] 答:错误,因为当第一次students.RemoveAt(0);后,数组中剩下2个元素,索引值为0、1,而下一行students.RemoveAt(1);则把索引值位1的元素删除了,而现在ArrayList中只剩下一个元素,下面紧接着又出现了students.RemoveAt(2);但是此时数组中只有一个元素,因此,此处会报错 (下面这个建议不讲~~) 请看下面一段代码,请问会输出什么? [csharp ] public struct student { public student(string name, int age) { Name = name; Age = age; } public string Name; public int Age; } class Program { static void Main(string[] args) { student stu1 = new student("张三",20); student stu2 = new student("李四", 20); student stu3 = new student("王五", 20); ArrayList students = new ArrayList(); students.Add(stu1); students.Add(stu2); students.Add(stu3); foreach (student stu in students) { student myStudent = (student)stu; myStudent.Age = 60; //看这里看这里看这里 } foreach (student stu in students) { Console.WriteLine(stu.Age); } } } [/csharp] 答案是不会,会输出20~ 请问ArrayList中现在有几个元素 [csharp ]Student stu2 = new Student("Scofield", Genders.Male, 28, "越狱狱");[/csharp] //这条数据已经被添加到ArrayList中 ArrayList中目前有3个元素 我再定义一个stu2但是不添加到ArrayList中 [csharp ] Student stu2 = new Student("Scofield", Genders.Male, 28, "越狱狱"); Students.Remove(stu2); [/csharp] 答案是不变,依旧为3个 HashTable 前面我们学习到了索引器来访问数组,很是方便,那我们能不能用类似索引器那种,通过关键字来获取对象呢?Yes it is!担不是ArrayList而是HashTable。 HashTable的数据是通过键和值来组织的(Key and Value)。 按我个人的理解可以参考ListView的ListViewItem与SubItem的关系 首先我们定义一个HashTable,HashTable和ArrayList一样都来自于是System.Collections的,因此不要忘了using System.Collections; 好了,我们来看下如何往HashTable中添加数值 [csharp ] Hashtable Students = new Hashtable(); Student scofield = new Student("Scofield", Genders.Male, 28, "越狱狱"); Student zhang = new Student("张靓靓", Genders.Female, 20, "唱歌歌"); Student jay = new Student("周杰杰", Genders.Male, 21, "耍双节棍棍"); Students.Add(scofield.Name, scofield); Students.Add(zhang.Name, zhang); Students.Add(jay.Name, jay); [/csharp] 怎么样很简单吧~,Ok,Go on 嗯,会添加那我们也得会取~ [csharp ]Student stu2 = (Student)Students["周杰杰"];[/csharp] 怎么?太简单了?会了才叫简单~Understand? 依照惯例 下面就是遍历了,HashTable既然是Key----Value对应关系的,遍历时我们也多了一种选择 我们可以遍历Value [csharp ] foreach (Object stuo in Students.Values) { Student stu = (Student)stuo; Console.WriteLine(stu.Name); } [/csharp] 同样也可以遍历Key [csharp ] foreach (string name in students.Keys) { Console.WriteLine(name); } [/csharp] 但是也同样是因为Key----Value对应关系,HashTable是不能通过索引来访问的。 现在会添会取会遍历,嗯?好像少点什么~呃~~删除 与ArrayList类似,HashTable的删除也是 Students.Remove("周杰杰"); 当然Remove()里面方的是key而不是Value,这一点一定要注意 泛型 首先看段代码((其实这里我也很头疼~~~) [csharp ] ArrayList Students = new ArrayList(); Student scofield = new Student("Scofield", Genders.Male, 28, "越狱狱"); Student zhang = new Student("张靓靓", Genders.Female, 20, "唱歌歌"); Student jay = new Student("周杰杰", Genders.Male, 21, "耍双节棍棍"); //创建一个老师对象 Teacher jacky = new Teacher("成龙龙", 4); Students.Add(scofield); Students.Add(zhang); Students.Add(jay); //将老师对象添加到ArrayList Students.Add(jacky); [/csharp] 添加是不会有问题的,但是当我们取的时候就会出现 <a href="http://harde.org/blog/wp-content/uploads/2008/12/e697a0e6a087e9a2981.jpg"><img src="http://harde.org/blog/wp-content/uploads/2008/12/e697a0e6a087e9a2981.jpg" alt="e697a0e6a087e9a2981" title="e697a0e6a087e9a2981" width="406" height="260" class="alignnone size-full wp-image-789" /></a> 从代码来看很明显,我们把Teacher对象添加到了学生的集合里,当取的时候进行类型转换时就会出错 怎么办呢?那就得请出本节课的BOSS,泛型与泛型集合 泛型:泛型是C#2.0中的一个新特性。通过泛型可以定义类型安全的数据类型,它的最显著应用就是创建集合类,可以约束集合类内的元素类型,比较典型的就是List<T>,Dictionary<K,V>(<T>、<K,V>表示该泛型集合中的元素类型) 泛型集合List<T>使用的是System.Collections.Generic命名空间,这点有别于ArrayList与HashTable。 List<T>的使用非常类似与ArrayList,只不过相当于了ArrayList List<T>有更好的安全性 我们首先定义一个List<T> [csharp ]List<Student> students = new List<Student>();
我们再次尝试一下开头的代码
Student scofield = new Student("Scofield", Genders.Male, 28, "越狱狱"); Student zhang = new Student("张靓靓", Genders.Female, 20, "唱歌歌"); Student jay = new Student("周杰杰", Genders.Male, 21, "耍双节棍棍"); Teacher jacky = new Teacher("成龙龙", 4); students.Add(scofield); students.Add(zhang); students.Add(jay);
看,在编译时立即就出错了
对于 List
在遍历时有点区别,就是List
下面我们看下 泛型集合Dictionary
刚才说过了List
同样的Dictionary
我们先来定义一个Dictionary
Dictionary<String, Student> students = new Dictionary<string, Student>(); Student scofield = new Student("Scofield", Genders.Male, 28, "越狱狱"); Student zhang = new Student("张靓靓", Genders.Female, 20, "唱歌歌"); Student jay = new Student("周杰杰", Genders.Male, 21, "耍双节棍棍");
添加数据
students.Add(scofield.Name, scofield); students.Add(zhang.Name, zhang); students.Add(jay.Name, jay);
完全和HashTable是一样的
最后我们来看下HashTable与Dictionary