写在前面:
最近在学习.Net的集合框架,看了许多博文,也看了书,总感觉不是很明白。心里疑惑很多,每天郁闷度日。如果学技术时感到很痛苦,有两种可能,其一是学习方法不对;其二是真的不适合。希望大多数搞技术的朋友都不属于后者。方法不对,那得找解决方法呀,于是乎网上一顿狂搜,也没发现有价值的文章。同样地,我搜索了一下Java的集合类,文章一堆,图片更少满天飞。而.Net连一张像样的说明图片都没有,觉得微软的技术总是藏着掖着,放佛怕人知道似的。不知道各位有没有这样的想法!?
不过话又说回来,这样也好,越是不想让我知道,我就越想知道,自己总结出来的东西才记忆深刻!
上面这幅图是Java的。
下面就把这几天的学习成果总结一下,与朋友们共享,有纰漏的地方还望指点!
集合,表示可以通过遍历每个元素来访问的一组对象(特别是可使用foreach循环访问)。一个集合包括多个元素,即有一个集合类对象和N个元素对象。
因为任何集合类都实现了IEnumerable接口,所以任何集合类对象都有一个GetEnumerator()方法,该方法可以返回一个实现了 IEnumerator接口的对象,这个返回的IEnumerator对象既不是集合类对象,也不是集合的元素类对象,它是一个独立的类对象。通过这个对象,可以遍历访问集合类对象中的每一个元素对象
如果集合类是用户自定义的集合类,则用户必须实现它的GetEnumerator()方法,否则不能使用循环。当然,与这个自定义集合类对应的IEnumerator类(实现了该接口的类),也要自定义一个才行。
这张图是用Reflector(这是个好东西)查看System.Collections命名空间。
可以看到,.Net Framework中的System.Collections命名空间下共有6个基本的集合类,分别是ArrayList,BitList,Hashtable,Queue,Stack以及SortedList。
一、ArrayList
ArrayList类是一个特殊的数组。通过添加和删除元素,就可以动态改变数组的长度。
ArrayList把所有元素都当作object对象引用,因而在访问ArrayList的元素时要进行类型转换。
随着不断向 ArrayList 中添加元素,容量通过重新分配按需自动增加,通常每次2倍的增加。如果需要建立一个对象数组,但不能预先知道数组的大小,就可以使用ArrayList
优点:动态改变大小、灵活方便的插入和删除元素、可排序
缺点:插入时性能不如数组、不是强类型的
属性或方法 |
描述 |
Count |
ArrayList中元素的个数 |
Capacity |
ArrayList中可包含的元素个数 |
Add() |
向ArrayList中添加一个对象返回int值 |
Clear() |
从ArrayList中移除所有元素 |
Contains() |
是否包含指定元素true/false |
IndexOf() |
返回指定对象第一次出现的索引值 |
Insert() |
在指定索引位置插入一个对象 |
Remove() |
移除指定对象的第一个匹配 |
RemoveAt() |
移除指定索引位置的对象 |
RemoveRange() |
从指定索引开始移除指定数量的元素 |
Sort() |
对ArrayList进行排序 |
TrimToSize() |
将Capacity设为当前所包含元素的个数 |
ArrayList的主要属性和方法
测试代码:
1 ArrayList arrayList = new ArrayList(5);
2
3
4
5 arrayList.Add(1);
6
7 arrayList.Add("test");
8
9 arrayList.Add(3);
10
11 arrayList.Add("four");
12
13 arrayList.Add(5);
14
15 arrayList.Add(6);
16
17
18
19 arrayList.Remove(1);
20
21 try
22
23 {
24
25 arrayList.RemoveRange(0, 2);
26
27 }
28
29 catch (ArgumentException ae)
30
31 {
32
33 Console.WriteLine(ae.Message);
34
35 }
36
37
38
39 Console.WriteLine(arrayList.Count + "\t" + arrayList.Capacity);
40
41
42
43 arrayList.TrimToSize();
44
45
46
47 Console.WriteLine(arrayList.Count + "\t" + arrayList.Capacity + "\n");
48
49
50
51 IEnumerator enumrator = arrayList.GetEnumerator();
52
53 StringBuilder buffer = new StringBuilder();
54
55
56
57 while (enumrator.MoveNext())
58
59 {
60
61 buffer.Append(enumrator.Current + "\t");
62
63 }
64
65 Console.WriteLine(buffer);
66
67
68
69
70
71
72
73 foreach (var item in arrayList)
74
75 {
76
77 Console.WriteLine(item);
78
79 }
二、Stack
Stack是堆栈,后进先出的访问各个元素。
可以调用Stack对象的GetEnumerator()方法,得到IEnumerator对象,来遍历堆栈中的各个元素
属性或方法 |
描述 |
Count |
Stack中元素的个数 |
Push() |
Stack中可包含的元素个数 |
Pop() |
向Stack中添加一个对象返回int值 |
Peek() |
从Stack中移除所有元素 |
Contains() |
Stack是否包含指定指定元素 |
Stack的主要属性和方法
测试代码:
1 Stack stack = new Stack();
2
3
4
5 stack.Push("first");
6
7 stack.Push("second");
8
9
10
11
12
13 Console.WriteLine("Count is : " + stack.Count);
14
15
16
17 Console.WriteLine("Top is: " + stack.Peek());
18
19
20
21 stack.Pop(); // second pop
22
23
24
25 stack.Pop(); // first pop
26
27
28
29 try
30
31 {
32
33 stack.Pop(); // Pop() 引发 InvalidOperationException异常
34
35 }
36
37 catch (InvalidOperationException ex)
38
39 {
40
41 Console.WriteLine(ex.Message);
42
43 }
44
45
46
47 IEnumerator enumrator = stack.GetEnumerator();
48
49 StringBuilder buffer = new StringBuilder();
50
51
52
53 while (enumrator.MoveNext())
54
55 {
56
57 buffer.Append(enumrator.Current + "\t");
58
59 }
60
61 Console.WriteLine(buffer);
三、哈希表,Hashtable
在.NET Framework中,Hashtable是System.Collections命名空间提供的一个容器,用于处理和表现类似key/value的键值对,其中key通常可用来快速查找,同时key是区分大小写;value用于存储对应于key的值。Hashtable中key/value键值对均为object类型,所以Hashtable可以支持任何类型的key/value键值对.
属性或方法 |
描述 |
Count |
返回Hashtable中元素的个数 |
Add() |
向Hashtable中添加元素 |
Clear() |
向Hashtable中移除所有元素 |
Remove(key) |
从Hashtable中移除指定的元素 |
Contains() |
Hashtable是否包含指定指定元素 |
测试代码: |
1 // 创建一个Hashtable实例
2
3 Hashtable ht = new Hashtable();
4
5 // 添加key/value键值对
6
7 ht.Add("E", "e");
8
9 ht.Add("A", "a");
10
11 ht.Add("C", "c");
12
13 ht.Add("B", "b");
14
15
16
17 // 判断哈希表是否包含特定键值,其返回值为true或false
18
19 if (ht.ContainsKey("E"))
20
21 {
22
23 Console.WriteLine("The key E exists.");
24
25 }
26
27
28
29 //ht.Remove("C"); // 移除一个key/value键值对
30
31 Console.WriteLine(ht["A"]); // 利用索引 此处输出a
32
33
34
35 //ht.Clear(); // 移除hashtable中的所有key/value键值对
36
37
38
39 //Console.WriteLine(ht["A"]); // 此处不会有任何输出,因为所有的元素都被清空了
40
41
42
43 // 遍历哈希表
44
45 foreach(DictionaryEntry de in ht)
46
47 {
48
49 Console.Write(de.Key + ":");
50
51 Console.WriteLine(de.Value);
52
53 }
54
55
56
57 // 对哈希表进行排序
58
59 // 哈希表中key按一定规则排序,实际上这是不可能实现的,因为哈希表中存放的是key/value键值对
60
61 // 所以需要采取一种变通的的做法
62
63 ArrayList al = new ArrayList(ht.Keys);
64
65
66
67 al.Sort(); // 按字母顺序进行排序
68
69
70
71 Console.WriteLine("After Sorted:");
72
73
74
75 // 排序后输出
76
77 foreach (string skey in al)
78
79 {
80
81 Console.Write(skey + ":");
82
83 Console.WriteLine(ht[skey]);
84
85 }
86
87 //string s = (string)ht["A"];//需要拆箱
四、SortedList
SortedLIst兼顾了ArrayList和Hashtable的优点,可按键值来排序。
SortedLIst表示key/value键值对的集合,与哈希表类似,区别在于SortedList中的key是排好序的数组。
测试代码:
1 SortedList sl = new SortedList();
2
3 sl["c"] = 41;
4
5 sl["a"] = 42;
6
7 sl["b"] = 11;
8
9 sl["d"] = 13;
10
11
12
13 Console.WriteLine("这是从SortedList里输出的:");
14
15 foreach (DictionaryEntry de in sl)
16
17 {
18
19 string s = (string)de.Key;
20
21 int i = (int)de.Value;
22
23 Console.WriteLine("{0},{1}", s, i);
24
25 }
完毕!