先來(lái)了解下集合的基本信息 1、BCL中集合類型分為泛型集合與非泛型集合,。 2,、非泛型集合的類和接口位于System.Collections命名空間。 3,、泛型集合的類和接口位于System.Collections.Generic命名空間,。 ICollection接口是System.Collections命名空間中非泛型集合類的基接口,它繼承自IEnumerable接口,,從IEnumerable接口繼承意味著實(shí)現(xiàn)該接口的實(shí)現(xiàn)類需要實(shí)現(xiàn)一個(gè)枚舉器方法:GetEnumerator,,該方法返回IEnumerator類型的數(shù)據(jù)。IDictionary和IList接口繼承自ICollection作為更為專用的接口,,其中IDictionary接口是鍵/值對(duì)接口,,它的實(shí)現(xiàn)如HashTable類;而IList是值的集合,其成員可通過(guò)索引訪問(wèn),,如ArrayList類,,次類集合與數(shù)組相比,可以認(rèn)為是可變的集合,,優(yōu)點(diǎn)有,,長(zhǎng)度自動(dòng)增長(zhǎng)等。IEnumerable<T>和IEnumerable是所有集合或集合接口的基接口,,所有集合接口或集合都繼承,、實(shí)現(xiàn)了它。其中IEnumerable是最底層的接口,。在非泛型集合里存放的都是System.Object類型,。 一、下面列出非泛型和泛型集合的接口 非泛型集合接口 泛型集合接口 說(shuō)明 ICollection ICollection<T> 定義所有集合的大小(Count),,枚舉器(foreach)和同步(copyto)方法,,繼承自IEnumerable IList IList<T> 表示可按照索引單獨(dú)訪問(wèn)的一組對(duì)象(像數(shù)組一樣) IDictionary IDictionary<T> 表示鍵/值對(duì)的集合 IComparer IComparer<T> 定義類型為比較兩個(gè)對(duì)象而實(shí)現(xiàn)的方法 IEqualityComparer IEqualityComparer<T> 定義方法以支持對(duì)象的相等比較 IEnumerable IEnumerable<T> 公開(kāi)枚舉器,。實(shí)現(xiàn)了該接口意味著允許foreach語(yǔ)句循環(huán)訪問(wèn)集合中的元素 IEnumerator IEnumerator<T> 支持在泛型集合上進(jìn)行簡(jiǎn)單迭代 下面來(lái)詳細(xì)介紹各種集合接口和集合。個(gè)人認(rèn)為應(yīng)該從根底說(shuō)起,。 先抱著MSDN來(lái)說(shuō)IEnumerable,,擴(kuò)展方法就不說(shuō)了,擴(kuò)展方法跳過(guò),,留到學(xué)Linq的時(shí)候再說(shuō),。 1、IEnumerable接口就一個(gè)方法,,沒(méi)有屬性,。 方法 說(shuō)明 GetEnumerator 返回一個(gè)循環(huán)訪問(wèn)集合的枚舉數(shù)。 實(shí)現(xiàn)或繼承了該接口,,就是為了這個(gè)方法,,可以foreach遍歷。 2,、IEnumerable<T>接口也一樣,,也是就一個(gè)方法,沒(méi)有屬性,。 方法 說(shuō)明 GetEnumerator 返回一個(gè)循環(huán)訪問(wèn)集合的枚舉數(shù),。 3、ICollection接口 方法 說(shuō)明 CopyTo 從特定的 Array 索引處開(kāi)始,,將 ICollection 的元素復(fù)制到一個(gè) Array 中,。 屬性 Count 獲取 ICollection 中包含的元素?cái)?shù)。 原來(lái)Count的源頭在這里,。 4,、ICollection<T> 方法 說(shuō)明 Count 獲取 ICollection<(Of <(T>)>) 中包含的元素?cái)?shù)。 屬性 Add 將某項(xiàng)添加到 ICollection<(Of <(T>)>) 中。 這個(gè)ICollect<T>,才開(kāi)始有點(diǎn)集合的影子了,,可以Add,、Clear了,怪不得它作為泛型集合接口的基類,。 5,、IList IList繼承了ICollection和IEnumerable 方法 說(shuō)明 Add 將某項(xiàng)添加到 IList 中。 屬性 Count 獲取 ICollection 中包含的元素?cái)?shù)。 (繼承自 ICollection,。) 可以看到,在不斷的繼承過(guò)程中,,這些接口不斷地添加自己的東西,,越繼承越多,越繼承越多,。 6,、IList<T> IList<T>繼承了ICollection<T>,IEnumerable<T>,IEnumerable 方法 說(shuō)明 Add 將某項(xiàng)添加到 ICollection<(Of <(T>)>) 中。 (繼承自 ICollection<(Of <(T>)>),。) 屬性 Count 獲取 ICollection<(Of <(T>)>) 中包含的元素?cái)?shù),。 (繼承自 ICollection<(Of <(T>)>)。) 同樣,,在不斷的繼承中,增加了新的東西,,功能也越來(lái)越強(qiáng)大,,支持索引獲取和設(shè)置就是IList<T>這個(gè)源頭的。一直弄不明白,,NHibernate為什么會(huì)選擇這個(gè)接口來(lái)返回?cái)?shù)據(jù),,其實(shí)這個(gè)接口的東西夠用了。 7,、IDictionary<TKey,TValue>接口 IDictionary<TKey,TValue>是最底層出現(xiàn)的鍵/值對(duì)集合了,相當(dāng)于值集合中的ICollection<T> 方法 說(shuō)明 Add 已重載,。 屬性 Count 獲取 ICollection<(Of <(T>)>) 中包含的元素?cái)?shù),。 (繼承自 ICollection<(Of <(T>)>)。) 該接口提供的功能和ICollection<T>差不多,,其實(shí)就是鍵/值對(duì)的開(kāi)宗立派者,。 8、IDictionary 方法 說(shuō)明 Add 在 IDictionary 對(duì)象中添加一個(gè)帶有所提供的鍵和值的元素,。 屬性 Count 獲取 ICollection 中包含的元素?cái)?shù)。 (繼承自 ICollection,。) 9,、ISet<T> ISet<T>同樣是繼承自ICollection<T>,IEnumerable<T>,IEnumerable 方法 說(shuō)明 Add(T) 將某項(xiàng)添加到 ICollection<T> 中,。 (繼承自 ICollection<T>。) 記住這些接口之間的關(guān)系,,其實(shí)是非常重要的,,方法和屬性記不全也無(wú)所謂,但是需要記住各自提供的功能,,以及繼承關(guān)系,。 先說(shuō)IComparer接口,這個(gè)接口就一個(gè)方法,,用于如何比較兩個(gè)對(duì)象 public class StringLengthComparer : IComparer<string> { public int Compare(string s1, string s2) { if (s1.Length > s2.Length) { return (1); } else if (s1.Length < s2.Length) { return (2); } else { return (0); } } } 說(shuō)完了集合接口,,現(xiàn)在開(kāi)始說(shuō)集合,。 1,、ArrayList ArrayList實(shí)現(xiàn)了IList、ICollection,、IEnumerable接口,。 ArrayList與Array的名字很相似,,現(xiàn)在來(lái)比較一下兩者的異同。 相同點(diǎn): (1),、兩者都實(shí)現(xiàn)了IList,、ICollection、IEnumerable接口,。 (2),、兩者都可以使用整數(shù)索引訪問(wèn)集合中的元素,包括讀取和賦值,,且集合中的索引都從0開(kāi)始,。 不同點(diǎn): (1)、ArrayList是集合,,而Array是數(shù)組,。 (2)、ArrayList是具體類,,Array是抽象類,。 (3)、數(shù)組必須在實(shí)例化時(shí)指定元素的數(shù)量,,該數(shù)量一旦確定就不可以更改了,,而ArrayList擴(kuò)展了這一點(diǎn),當(dāng)實(shí)例化一個(gè)ArrayList實(shí)例時(shí)可以不指定集合元素?cái)?shù)(有默認(rèn)初始容量),,當(dāng)然你也可以指定初始容量,。 (4)、獲取數(shù)組的元素?cái)?shù)時(shí)使用Length屬性,,而獲取ArrayList集合的元素?cái)?shù)時(shí)使用Count屬性,。 (5)、數(shù)組可以有多維,,而ArrayList只能是一維,。 來(lái)看ArrayList具體提供的功能 屬性 說(shuō)明 Capacity 獲取或設(shè)置 ArrayList 可包含的元素?cái)?shù)。 方法 Adapter 為特定的 IList 創(chuàng)建 ArrayList 包裝。 static void Main(string[] args) { ArrayList arrayList = new ArrayList(); arrayList.Add(1); //Add方法,,將一個(gè)元素添加到ArrayList中 arrayList.Add("你好"); arrayList.Add(3.265); IList iList = arrayList; ICollection iCollection = iList; IEnumerable iEnumerable = iCollection; //體現(xiàn)了ArrayList的繼承關(guān)系 foreach (object obj in iEnumerable) { Console.WriteLine(obj.ToString()); } bool b = arrayList.Contains("你好"); //確定ArrayList中是否包含某元素 Console.WriteLine(b); //輸出 True object[] objArr = new object[arrayList.Count + 1]; objArr[0] = "我是用來(lái)占位的"; arrayList.CopyTo(objArr, 1); //便宜一位,,也就是接受數(shù)組從1開(kāi)始,,默認(rèn)是0 foreach (object obj in objArr) { Console.Write(obj.ToString() + "-"); //輸出 我是用來(lái)占位的-1-你好-3.265- } Console.WriteLine(); ArrayList AL = ArrayList.FixedSize(arrayList); //靜態(tài)方法 返回一個(gè)固定大小的ArrayList對(duì)象,數(shù)量不許改變,。也就是說(shuō)不能添加和刪除,。 Console.WriteLine(AL.IsFixedSize); //輸出True //AL.Add(111); 此處報(bào)異常,"集合的大小是固定的" ArrayList ALReadOnly = ArrayList.ReadOnly(arrayList); Console.WriteLine(ALReadOnly.IsReadOnly); //輸出True ArrayList AL1 = arrayList.GetRange(1, 2); //按照索引順序截取出子集 foreach (object obj in AL1) { Console.Write(obj.ToString()); //輸出 你好3.265 可以截取出的新ArrayList只包含1,2位 } Console.WriteLine(); int indexLocation = arrayList.IndexOf(1); //從左邊開(kāi)始檢索,,返回第一個(gè)匹配到的元素的順序 Console.WriteLine(indexLocation); //輸出 0 arrayList.Add(1); //為了體現(xiàn)LastIndexOf的不同,,先添加一個(gè)1 int lastLocation = arrayList.LastIndexOf(1); Console.WriteLine(lastLocation); //返回3 arrayList.Insert(2, "Insert插入的元素"); //這個(gè)方法與Add的不同在于它可以在任意位置插入 foreach (object obj in arrayList) { Console.Write(obj.ToString() + " "); //輸出 1 你好 Insert插入的元素 3.265 1 } ArrayList arr = new ArrayList(); arr.Add(1); arr.Add(2); arrayList.AddRange(arr); foreach (object obj in arrayList) { Console.Write(obj.ToString() + "-"); //輸出 1 你好 Insert插入的元素 3.265 1 1 2可以看到將一個(gè)新的集合追加到了最后 } arrayList.Remove(2); foreach (object obj in arrayList) { Console.Write(obj.ToString() + "-"); //輸出 1 你好 Insert插入的元素 3.265 1 1 可以看到2已經(jīng)被移除了 } Console.WriteLine(); arrayList.RemoveAt(0); foreach (object obj in arrayList) { Console.Write(obj.ToString() + "-"); //輸出 你好 Insert插入的元素 3.265 1 1 可以看到第0個(gè)元素"2"已經(jīng)被移除了 } Console.WriteLine(); //arrayList.Reverse(); //foreach (object obj in arrayList) //{ // Console.Write(obj.ToString() + "-"); //輸出順序倒轉(zhuǎn)的所有元素 //} ArrayList AL3 = new ArrayList(); arrayList.SetRange(0,AL3); //從第0位開(kāi)始,將元素復(fù)制到AL3中 foreach (object obj in AL3) { Console.Write(obj.ToString() + "-"); //輸出 你好 Insert插入的元素 3.265 1 1 } object[] objArrs = new object[arrayList.Count]; objArrs = arrayList.ToArray(); foreach (object obj in objArrs) { Console.Write(obj.ToString() + "-"); } Console.WriteLine(); arrayList.Capacity = 5; //讀取或設(shè)置可包含元素的數(shù)量,,如果小于當(dāng)前會(huì)報(bào)錯(cuò),。 Console.WriteLine(arrayList.Count); //輸出5 arrayList.TrimToSize(); Console.WriteLine(arrayList.Count); //輸出5 Console.ReadKey(); } 2、非泛型集合HashTable Hashtable實(shí)現(xiàn)了IDictionary,、ICollection以及IEnumerable接口,。注意Hashtable,t是小寫的,。由于是非泛型集合,,因此存儲(chǔ)進(jìn)去的都是object類型,不管是鍵還是值,。 Hashtable的要點(diǎn),。 (1)、Hashtable僅有非泛型版本,。 (2),、Hashtable類中的鍵不允許重復(fù),但值可以,。 (3),、Hashtable類所存儲(chǔ)的鍵值對(duì)中,值可以為null,,但鍵不允許為null,。 (4)、Hashtable不允許排序操作,。 以下給出一個(gè)實(shí)例,,Hashtable提供的功能是在于ArraryList差不多,只不過(guò)存儲(chǔ)的是鍵值對(duì)而已,。只寫個(gè)基本短小的示例,。 static void Main(string[] args) { Hashtable ht = new Hashtable(); ht.Add(1,1); ht.Add("我愛(ài)你","是嗎,?"); Console.WriteLine(ht.Count); //輸出 2 Console.WriteLine(ht["我愛(ài)你"]); //輸出 "是嗎?" 用鍵 獲取值 Console.WriteLine(ht.Contains(1)); //輸出True Console.ReadKey(); } 3,、Queue和Queue<T> Queue成為隊(duì)列,,隊(duì)列是這樣一種數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)有列表的一端插入,,并由列表的另一端移除,。就像單行道,只能從一段進(jìn),,從一端出,。Queue類實(shí)現(xiàn)了ICollection和IEnumerable接口。 Queue的一些重要特性,。 1,、先進(jìn)先出 2、可以添加null值到集合中 3,、允許集合中的元素重復(fù) 4,、Queue容量會(huì)按需自動(dòng)添加 5、Queue的等比因子是當(dāng)需要更大容量時(shí)當(dāng)前容量要乘以的數(shù)字,,默認(rèn)是2.0,。 現(xiàn)在列出Queue一個(gè)特性的功能 成員 類型 說(shuō)明 Clear 方法 從Queue中移除所有對(duì)象,清空隊(duì)列,。 Contains 方法 確定某元素是否在Queue中 Enqueue 方法 將對(duì)象添加到Queue的結(jié)尾處 入列 Dequeue 方法 移除并返回位于Queue開(kāi)始處的對(duì)象 出列 Peek 方法 返回位于Queue開(kāi)始出的對(duì)象,,但不將其移除,與出列不同,,出列是會(huì)移除的 提供的功能都是差不多的,,現(xiàn)在給出一個(gè)實(shí)例,主要顯示Queue的作用,。 static void Main(string[] args) { Queue q = new Queue(); q.Enqueue(1); q.Enqueue("想家了!"); q.Enqueue(1.23); Console.WriteLine(q.Peek()); //輸出1 獲取值但不移除,,與出列不同 int Count = q.Count; //出隊(duì)的時(shí)候q.Count在變化,因此q.Count放在循環(huán)條件里是不妥的 for (int i = 0; i < Count; i++) { Console.WriteLine(q.Dequeue().ToString()); //注意 輸出 1 想家了 1.23 都是從最先添加的先拿 } Console.WriteLine(q.Count); //輸出0 出列一次,,就自動(dòng)移除了,。 Queue<int> qInt = new Queue<int>(); qInt.Enqueue(1); qInt.Enqueue(2); qInt.Enqueue(3); Console.WriteLine(qInt.Peek()); //輸出1 int IntCount = qInt.Count; for (int i = 0; i < IntCount; i++) { Console.WriteLine(qInt.Dequeue()); //注意 輸出 123 都是從最先添加的先拿 } Console.WriteLine(q.Count); //輸出0 出列一次,就自動(dòng)移除了,。 Console.ReadKey(); } 4,、Stack和Stack<T> Stack稱為棧,棧和隊(duì)列非常相似,,只不過(guò)隊(duì)列是先進(jìn)先出,,而棧中的數(shù)據(jù)添加和移除都在一端進(jìn)行,遵守棧中的數(shù)據(jù)則后進(jìn)先出,。Stack類實(shí)現(xiàn)了ICollection和IEnumerable接口,。 Stack類的一些重要特性如下: 1,、后進(jìn)先出。 2,、可以添加null值到集合中,。 3、允許集合中的元素重復(fù),。 4,、Stack的容量會(huì)按需自動(dòng)增加。 列出幾個(gè)有特點(diǎn)的功能,。 成員 類型 說(shuō)明 Clear 方法 從Stack中移除所有對(duì)象 Contains 方法 確定某元素是否在Stack中 Push 方法 將對(duì)象插入Stack的頂部 入棧 Pop 方法 移除并返回Stack頂部的對(duì)象 出棧 Peek 方法 返回位于Stack頂部的對(duì)象,,但不移除,,注意出棧是移除的,。它不移除僅僅返回。 Count 屬性 獲取Stack中包含的元素 static void Main(string[] args) { Stack s = new Stack(); s.Push(1); s.Push("想回家了,!"); s.Push(1.23); Console.WriteLine(s.Peek()); //輸出1.23 int Count = s.Count; //差點(diǎn)犯了邏輯錯(cuò)誤,,在for里面如果是s.Count的話,很容易亂,,因?yàn)槌鰲2僮鱯.Count是在變動(dòng)著的,。 for (int i = 0; i < Count; i++) { Console.WriteLine(s.Pop()); //輸出 1.23 想回家了 1 } Console.WriteLine(s.Count); //輸出0 Stack<int> sInt = new Stack<int>(); sInt.Push(1); sInt.Push(2); sInt.Push(3); Console.WriteLine(sInt.Peek()); //輸出3 int IntCount = sInt.Count; //差點(diǎn)犯了邏輯錯(cuò)誤,在for里面如果是s.Count的話,,很容易亂,,因?yàn)槌鰲2僮鱯.Count是在變動(dòng)著的。 for (int i = 0; i < IntCount; i++) { Console.WriteLine(sInt.Pop()); //輸出 3 2 1 } Console.WriteLine(sInt.Count); //輸出0 Console.ReadKey(); } 5,、SortedList與SortedList<T> SortedList類實(shí)現(xiàn)了IDictionary,、ICollection以及IEnumerable接口。SortedList類與HashTable類似,,也表示一個(gè)鍵/值對(duì)集合,,可以通過(guò)鍵和索引對(duì)元素進(jìn)行訪問(wèn),但不同的是,,也是該類的最大作用所在,,就是支持基于鍵的排序。在SortedList中,,鍵和值分別保存在一個(gè)數(shù)組中,,當(dāng)向Sorted添加一個(gè)元素時(shí),SortedList類添加一個(gè)元素時(shí),,SortedList會(huì)首先對(duì)key進(jìn)行排序,,然后根據(jù)排序結(jié)果計(jì)算出要插入到集合中的位置索引,再分別將key和value插入到各自數(shù)組的指定索引位置,。當(dāng)使用foreach循環(huán)集合中的元素時(shí),,SortedList會(huì)將相同索引位置的key和value放進(jìn)一個(gè)DictionaryEntry類型的對(duì)象,,然后返回。 看了下MSDN,,功能還是差不多,,而且不難看明白,實(shí)在沒(méi)力氣一個(gè)一個(gè)寫DEMO了,。 static void Main(string[] args) { SortedList SL = new SortedList(); SL.Add("txt","txt"); //Add的時(shí)候會(huì)自動(dòng)排序 SL.Add("jpg","jpg"); SL.Add("png","png"); foreach (DictionaryEntry de in SL) //返回的是DictionaryEntry對(duì)象 { Console.Write(de.Key + ":" + de.Value + " "); //輸出 jpg:jpg png:png txt:txt //注意這個(gè)順序啊,,添加的時(shí)候就自動(dòng)排序了 } Console.WriteLine(); SortedList<int,string> SLString = new SortedList<int,string>(); SLString.Add(3, "333"); SLString.Add(2, "222"); SLString.Add(1, "111"); foreach (KeyValuePair<int,string> des in SLString) //返回的是KeyValuePair,在學(xué)習(xí)的時(shí)候盡量少用var,,起碼要知道返回的是什么 { Console.Write(des.Key + ":" + des.Value + " "); } Console.ReadKey(); } 6,、BitArray BitArray類實(shí)現(xiàn)了一個(gè)位結(jié)構(gòu),它是一個(gè)二進(jìn)制位(0和1)的集合,。BitArray的值表示true或false,。true表示位打開(kāi),false表示位關(guān)閉,。BitArray實(shí)現(xiàn)了ICollection和IEnumerable接口,。 BitArray的一些特性如下: 1、BitArray集合不支持動(dòng)態(tài)調(diào)整,,因此沒(méi)有Add和Remove方法,。 2、若需要調(diào)整集合的大小,,可通過(guò)設(shè)置屬性Length的值來(lái)實(shí)現(xiàn),。 3、集合中的索引從0開(kāi)始,。 4,、使用BitArray(int length)構(gòu)造函數(shù)初始化BitArray集合后,其值均為false,。 5,、BitArray集合之間支持按位“或”、“異或”,、“與運(yùn)算”,,參與這三類運(yùn)算的BitArray集合長(zhǎng)度必須相等。否則會(huì)拋出異常,。 抱著MSDN來(lái)學(xué)習(xí)下: 屬性 說(shuō)明 Count 獲取 BitArray 中包含的元素?cái)?shù),。 方法 說(shuō)明 And 對(duì)當(dāng)前 BitArray 中的元素和指定的 BitArray 中的相應(yīng)元素執(zhí)行按位 AND 運(yùn)算。 static void Main(string[] args) { BitArray BA = new BitArray(3); BA[0] = true; BA[1] = false; BA[2] = true; BitArray BB = new BitArray(3); BA[0] = true; BA[1] = false; BA[2] = true; BitArray BOr = BA.Or(BB); //與運(yùn)算,返回一個(gè)新的BitArray foreach (var b in BOr) { Console.Write(b + "-"); //True-False-True } Console.ReadKey(); }
|
|