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



