记录Harde学习成长生活的点点滴滴.
« »

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值,代表了刚才添加元素的索引)
请看示例

?View Code CSHARP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 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类型存放的
因此再取的时候要转换成原来的数据类型
请看以下代码

?View Code CSHARP
1
2
         Student stu1 = (Student)Students[0];
            stu1.SayHi();

这段代码就会调用出scofield的学员资料
e697a0e6a087e9a298
好了,会了存取下面我们得看下删除了,删除ArrayList中的数据也很简单
使用

?View Code CSHARP
1
2
3
ArrayList.Remove(对象名) //删除指定对象名的对象
ArrayList.RemoveAt(index) //删除指定索引的对象
ArrayList.Clear() //清除集合内的所有元素

这三个方法就可以
比如Students.RemoveAt(0);就会删除scofield的资料,(同样我们也可以这样删除ArrayList.Remove(scofield))
说道数组,就不得不提下“遍历”
在日常使用中“遍历是我们经常用到的东西,通常对于数组,我们都是用for循环语句来遍历的,同样的ArrayList也不例外,另外ArrayList还可以使用foreach来遍历
代码:

?View Code CSHARP
1
2
3
4
5
            for (int i = 0; i < Students.Count; i++)
            {
                Student stuFor = (Student)Students[i];
                Console.WriteLine(stuFor.Name);
            }

再来看看用foreach遍历

?View Code CSHARP
1
2
3
4
5
    foreach (Object stuo in Students)
            {
                Student stuForeach = (Student)stuo;
                Console.WriteLine(stuForeach.Name);
            }

这两种方法效果是一样的
但是有点区别,for是通过索引来访问元素,而foreach是通过对象来访问的。

常见错误
请问这样写对么?

?View Code CSHARP
1
2
3
4
5
6
7
8
9
10
11
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);

答:错误,因为当第一次students.RemoveAt(0);后,数组中剩下2个元素,索引值为0、1,而下一行students.RemoveAt(1);则把索引值位1的元素删除了,而现在ArrayList中只剩下一个元素,下面紧接着又出现了students.RemoveAt(2);但是此时数组中只有一个元素,因此,此处会报错

(下面这个建议不讲~~)
请看下面一段代码,请问会输出什么?

?View Code CSHARP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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);
            }
        }
}

答案是不会,会输出20~
请问ArrayList中现在有几个元素

?View Code CSHARP
1
Student stu2 = new Student("Scofield", Genders.Male, 28, "越狱狱");

//这条数据已经被添加到ArrayList中 ArrayList中目前有3个元素
我再定义一个stu2但是不添加到ArrayList中

?View Code CSHARP
1
2
Student stu2 = new Student("Scofield", Genders.Male, 28, "越狱狱");
Students.Remove(stu2);

答案是不变,依旧为3个

HashTable

前面我们学习到了索引器来访问数组,很是方便,那我们能不能用类似索引器那种,通过关键字来获取对象呢?Yes it is!担不是ArrayList而是HashTable。
HashTable的数据是通过键和值来组织的(Key and Value)。
按我个人的理解可以参考ListView的ListViewItem与SubItem的关系
首先我们定义一个HashTable,HashTable和ArrayList一样都来自于是System.Collections的,因此不要忘了using System.Collections;
好了,我们来看下如何往HashTable中添加数值

?View Code CSHARP
1
2
3
4
5
6
7
8
9
         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);

怎么样很简单吧~,Ok,Go on
嗯,会添加那我们也得会取~

?View Code CSHARP
1
Student stu2 = (Student)Students["周杰杰"];

怎么?太简单了?会了才叫简单~Understand?
依照惯例
下面就是遍历了,HashTable既然是Key—-Value对应关系的,遍历时我们也多了一种选择
我们可以遍历Value

?View Code CSHARP
1
2
3
4
5
            foreach (Object stuo in Students.Values)
            {
                Student stu = (Student)stuo;
                Console.WriteLine(stu.Name);
            }

同样也可以遍历Key

?View Code CSHARP
1
2
3
4
foreach (string name in students.Keys)
{
       Console.WriteLine(name); 
}

但是也同样是因为Key—-Value对应关系,HashTable是不能通过索引来访问的。
现在会添会取会遍历,嗯?好像少点什么~呃~~删除
与ArrayList类似,HashTable的删除也是
Students.Remove(“周杰杰”);
当然Remove()里面方的是key而不是Value,这一点一定要注意

泛型
首先看段代码((其实这里我也很头疼~~~)

?View Code CSHARP
1
2
3
4
5
6
7
8
9
10
11
12
13
         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);

添加是不会有问题的,但是当我们取的时候就会出现
e697a0e6a087e9a2981
从代码来看很明显,我们把Teacher对象添加到了学生的集合里,当取的时候进行类型转换时就会出错
怎么办呢?那就得请出本节课的BOSS,泛型与泛型集合
泛型:泛型是C#2.0中的一个新特性。通过泛型可以定义类型安全的数据类型,它的最显著应用就是创建集合类,可以约束集合类内的元素类型,比较典型的就是List,Dictionary表示该泛型集合中的元素类型)
泛型集合List使用的是System.Collections.Generic命名空间,这点有别于ArrayList与HashTable。
List的使用非常类似与ArrayList,只不过相当于了ArrayList List有更好的安全性
我们首先定义一个List

?View Code CSHARP
1
List<Student> students = new List<Student>();

我们再次尝试一下开头的代码

?View Code CSHARP
1
2
3
4
5
6
7
         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);

看,在编译时立即就出错了
e697a0e6a087e9a2982
对于 List的操作,大家可以参照ArrayList,在此我就不再赘述。
在遍历时有点区别,就是List不需要类型转换~,为了方面大家对比两者关系,我画了张表
e697a0e6a087e9a2983
下面我们看下 泛型集合Dictionary
刚才说过了List与ArrayList相类似
同样的Dictionary也类似于HashTable,
我们先来定义一个Dictionary

?View Code CSHARP
1
2
3
4
5
            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, "耍双节棍棍");

添加数据

?View Code CSHARP
1
2
3
         students.Add(scofield.Name, scofield);
            students.Add(zhang.Name, zhang);
            students.Add(jay.Name, jay);

完全和HashTable是一样的

最后我们来看下HashTable与Dictionary的对比
e697a0e6a087e9a2984

日志信息 »

该日志于2008-12-17 01:06由 harde 发表在DotNet分类下, 你可以发表评论。除了可以将这个日志以保留源地址及作者的情况下引用到你的网站或博客,还可以通过RSS 2.0订阅这个日志的所有评论。

相关日志 »

没有评论

发表评论 »

使用新浪微博登陆

返回顶部
分享按钮