[转]迭代、集合、字典表和列表
集合在編程的過(guò)程中用的是非常的多,如GridViewRowCollection、ConnectionStringSettingsCollection、NameValueCollection等等。一般來(lái)說(shuō),集合的類都包含在System.Collections命名空間中。那眾多集合之間又有什么樣的聯(lián)系呢?這需要我們從集合的集成關(guān)系上理順一下。
一、IEnumerable和IEnumerator接口
??? IEnumberable接口是大部分集合類型的根。它是一個(gè)支持foreach迭代的接口,一個(gè)集合對(duì)象要能遍歷所有對(duì)象的話,那它必需要實(shí)現(xiàn)這個(gè)接口,它的聲明結(jié)構(gòu)如下:
??????? public interface IEnumerable
??????? {
??????????? IEnumerator GetEnumerator ();
??????? }
??? 其中的GetEnumerator方法返回的是IEnumerator類型,可以用返回的IEnumerator類型結(jié)果實(shí)現(xiàn)對(duì)集合內(nèi)容的向前遍歷。
??? IEnumerator接口的聲明如下:
public interface IEnumerator
?????? {
Object Current { get; }???? //獲取集合中的當(dāng)前元素。
bool MoveNext ();???????????? //如果枚舉成功推進(jìn)到下一個(gè)元素,則為 true;如果枚舉數(shù)越過(guò)集合的結(jié)尾,則為 false。
void Reset () ;??????????????????? //將枚舉數(shù)設(shè)置為其初始位置,該位置位于集合中第一個(gè)元素之前。????
}
??? 如在HashTable中用IEnumerator遍歷數(shù)據(jù)(關(guān)于Hashtable后面會(huì)有介紹):
Hashtable h = new Hashtable();
??????? h.Add("a","aaaa");
??????? h.Add("b", "bbbb");
??????? IEnumerator ie = h.GetEnumerator();
??????? while (ie.MoveNext())
??????? {
??????????? Console.Write(((DictionaryEntry)ie.Current).Key + "\t" + ((DictionaryEntry)ie.Current).Value+"\n");
??????? }
二、ICollection接口
??? ICollection接口派生自IEnumerable接口,擴(kuò)展了集合元素個(gè)數(shù)和同步功能(對(duì)多線程安全訪問(wèn)的支持)。
??? ICollection接口的聲明:
public interface ICollection : IEnumerable
?????? {
int Count { get; } ???????? //ICollection集合中元素的個(gè)數(shù)
bool IsSynchronized { get; }?? //獲取是否同步對(duì)ICollection 的訪問(wèn)。
Object SyncRoot { get; }???? //獲取用于同步ICollection訪問(wèn)的對(duì)象。
}?
?????? 所有實(shí)現(xiàn)ICollection接口的對(duì)象,可以在對(duì)集合元素遍歷的時(shí)候,把集合鎖定,以防其它線程(用戶)對(duì)集合的修改。
ArrayList al = new ArrayList();
??????? al.Add("aaa");
??????? al.Add("bbb");
lock (al.SyncRoot)
??????? {
??????????? for(int i=0;i<al.Count;i++)
??????????? {
??????????????? Console.WriteLine(obj);
??????????? }
??????? }
??? ICollection接口派生了IDictionary和IList兩個(gè)子接口。
三、IList接口
??? IList是一個(gè)值的集合,派生自ICollection,其成員可以通過(guò)索引訪問(wèn)。如ArrayList
??? IList接口的聲明:
public interface IList : ICollection, IEnumerable
??????? {
??????????? int Add(object value);????? //將某項(xiàng)添加到IList集合中
??????????? void Clear ();????? //從 IList 中移除所有項(xiàng)。
??????????? bool Contains (Object value);??? //確定 IList 是否包含特定值。
??????????? int IndexOf (Object value); //取得IList集合中指定項(xiàng)的索引號(hào)。
??????????? void Insert (int index,Object value); //將一個(gè)項(xiàng)插入IList集合的指定索引處。
??????????? void Remove(object value);?? //從IList集合中移除指定的項(xiàng)對(duì)象。
??????????? void RemoveAt(int index); //從IList集合中移除指定索引項(xiàng)的對(duì)象。
??????????? bool IsFixedSize { get; } //指示IList 是否具有固定大小。大小固定的集合在創(chuàng)建之后不允許添加或移除元素,但允許修改現(xiàn)有元素。
??????????? bool IsReadOnly { get; } //IList 是否為只讀。只讀集合在創(chuàng)建之后不允許添加、移除或修改元素。
??????????? Object this [int index] { get; set; } //獲取或設(shè)置指定索引號(hào)元素的內(nèi)容。可以使用此索引器實(shí)現(xiàn)集合元素的循環(huán)遍歷。
}
四、IDictionary接口
??? IDictionary接口實(shí)現(xiàn)一個(gè)“鍵/值”對(duì)的集合,派生自ICollection,可以用循環(huán)遍歷其中的每一個(gè)元素。其中的每個(gè)"鍵/值"對(duì)是一個(gè)DictionaryEntry 對(duì)象,只能用鍵名來(lái)存取對(duì)象,不能用索引號(hào)來(lái)存取對(duì)象。如HashTable
??? iDictionary接口的聲明:
public interface IDictionary : ICollection, IEnumerable
??????? {
??????????? void Add (Object key,Object value); //在IDictionary集合中添加鍵和值對(duì)元素。
??????????? void Clear ();????? //從 IList 中移除所有項(xiàng)。
??????????? bool Contains (Object value);??? //確定 IList 是否包含特定值。
??????????? IDictionaryEnumerator GetEnumerator (); //返回一個(gè)用于 IDictionary 集合的 IDictionaryEnumerator 對(duì)象。
??????????? void Remove (Object key);???? //從集合中移除指定鍵值的元素
??????????? bool IsFixedSize { get; } //指示IList 是否具有固定大小。大小固定的集合在創(chuàng)建之后不允許添加或移除元素,但允許修改現(xiàn)有元素。
??????????? bool IsReadOnly { get; } //IList 是否為只讀。只讀集合在創(chuàng)建之后不允許添加、移除或修改元素。
?????????? Object this [Object key] { get; set; } //獲取或設(shè)置具有指定鍵的元素。
??????????? ICollection Keys { get; } //獲取IDictionary中的所有的鍵集合。
??????????? ICollection Values { get; }?? //獲取IDictionary中的所有的值集合。
??????? }
五、ArrayList類
??? ArrayList類實(shí)現(xiàn)了IList接口,用來(lái)存儲(chǔ)非泛型對(duì)象。
Count屬性:集合中實(shí)際元素的個(gè)數(shù)。
Capacity屬性:ArrayList空間的大小。生成一個(gè)ArrayList對(duì)象的時(shí)候默認(rèn)分配了4個(gè)元素的空間(默認(rèn)),在添加前4個(gè)元素的時(shí)候Capacity始終是4。當(dāng)添加第5個(gè)元素的時(shí)候,首先框架會(huì)把ArrayList的Capacity的容量加倍,然后再把第5個(gè)元素存入。
??????? void AddRange (ICollection c):將一個(gè)新的ICollection對(duì)象加到當(dāng)前ArrayList后面,通常用來(lái)拼接兩個(gè)ArrayList。
??????? ArrayList GetRange (int index,int count):從當(dāng)前的ArrayList對(duì)象中返回指定位置和指定數(shù)目的元素,并將這些元素以新的ArrayList對(duì)象形式返回。
??????? void InsertRange(int index,ICollection c) :在指定的位置插入另一個(gè)ICollection對(duì)象。
??????? void TrimToSize():將ArrayList的容量縮減到ArrayList的實(shí)際的元素個(gè)數(shù)。
??????? void Reverse() :將數(shù)組的順序進(jìn)行返轉(zhuǎn)。
??????? void Sort():將數(shù)組進(jìn)行排序。
六、Hashtable類:
??? Hashtable實(shí)現(xiàn)了IDictionary接口,可以用來(lái)存儲(chǔ)非泛型對(duì)象。由于Hashtable實(shí)現(xiàn)的是IEnumerable接口,所以可以用foreach對(duì)Hashtable進(jìn)行遍歷。
??????? void ContainsKey(object o)?? //判斷Hashtable 是否包含指定鍵。
??????? void ContainsValue(object o)??? //判斷Hashtable是否包含指定的值。
??????? Hashtable Hashtable.Synchronized (Hashtable t) //靜態(tài)方法,將一個(gè)普通的Hashtable包裝為一個(gè)同步的(線程安全)Hashtable。
??? 用IEnumerator對(duì)Hashtable進(jìn)行顯示:
Hashtable h = new Hashtable();
??????? h.Add("a","aaaa");
??????? h.Add("b", "bbbb");
IEnumerator ie = h.GetEnumerator();
??????? while (ie.MoveNext())
??????? {
??????????? Console.Write(((DictionaryEntry)ie.Current).Key + "\t" + ((DictionaryEntry)ie.Current).Value+"\n");
??????? }
??? 用foreach來(lái)實(shí)現(xiàn)對(duì)Hashtable的迭代顯示:
??? Hashtable h = new Hashtable();
??????? h.Add("a","aaa");
??????? h.Add("b", "bbb");
foreach (DictionaryEntry d in h)
??????? {
??????????? Console.WriteLine(d.Key+"\t"+d.Value);
??????? }
??? 由于Keys和Values也是ICollection集合,所以也要以用foreach分別對(duì)Keys和Values集合進(jìn)行迭代
Hashtable h = new Hashtable();
??????? h.Add("a","aaa");
??????? h.Add("b", "bbb");????
??????? foreach (object var in h.Keys)
??????? {
??????????? Console.WriteLine(var);
??????? }
??????? foreach (object var in h.Values)
??????? {
??????????? Console.WriteLine(var);
??????? }??
七、SortedList類:
??? SortedList與散列表一樣也是一個(gè)"鍵/值"對(duì)的集合,但它是按照關(guān)鍵字進(jìn)行排序的,其值是可以通過(guò)數(shù)字索引來(lái)處理。??
???????????? object GetKey(int index)://根據(jù)索引號(hào)來(lái)取得指定位置的鍵。
???????????? object GetByIndex(int index)://根據(jù)索引號(hào)來(lái)取得指定位置的值。
???????????? IList GetKeyList()://獲取SortedList中的鍵的集合。
???????????? IList GetValueList()://獲取SortedList中的值的集合。
???????????? object IndexOfKey(object var)://取出SortedList中指定鍵的索引號(hào)。
???????????? object IndexOfValue(object var)://取出SortedList中指定值的索引號(hào)。
??? 用索引號(hào)遍歷SortedList中的每個(gè)元素
SortedList h = new SortedList();
??????????? h.Add("a","aaa");
??????????? h.Add("d","ddd");
??????????? h.Add("f", "fff");
??????????? h.Add("e", "eee");
??????????? h.Add("c","ccc");
??????????? h.Add("b", "bbb");????????????
??????????? for (int i = 0; i < h.Count; i++)
??????????? {
??????????????? Console.WriteLine(h.GetByIndex(i)+"\t"+h.GetKey(i));
??????????? }
?????? 從輸出的結(jié)果中,我們會(huì)發(fā)現(xiàn)其中的元素會(huì)按照key的順序進(jìn)行排序的。
?????? GetKeyList()和GetValueList()返回的都是IList類型的數(shù)據(jù),所以我們也可以使用foreach對(duì)二者的返回結(jié)果進(jìn)行迭代:
SortedList h = new SortedList();
??????????? h.Add("a","aaa");
??????????? h.Add("d","ddd");
??????????? h.Add("f", "fff");
??????????? h.Add("e", "eee");
??????????? h.Add("c","ccc");
??????????? h.Add("b", "bbb");
??????????? foreach (object var in h.GetKeyList())
??????????? {
??????????????? Console.WriteLine(var);
??????????? }
??????????? foreach (object var in h.GetValueList())
??????????? {
??????????????? Console.WriteLine(var);
??????????? }
八、Queue類和Stack類
??? 這兩個(gè)類都實(shí)現(xiàn)了ICollection接口和IEnumerable接口,但沒(méi)有實(shí)現(xiàn)IList接口。
??? Queue:隊(duì)列,先進(jìn)先出。
Enqueue(object var):入隊(duì)
??????? object Dequeue() :出隊(duì)
??????? object Peek():返回隊(duì)首的元素,但不移除
?????? 出隊(duì)和入隊(duì)都分影響Queue對(duì)象的元素的個(gè)數(shù),即影響其Count屬性。
Queue q = new Queue();
??????????? q.Enqueue("aaa");
??????????? q.Enqueue("bbb");
??????????? q.Enqueue("ccc");
??????????? for (int i = 0; i < 3; i++) //這里用的是i<3而不是i<q.Count,因?yàn)镈equeue的過(guò)程中會(huì)影響q.Count。
??????????? {
??????????????? Console.WriteLine(q.Dequeue());
??????????? }
??? Stack:堆棧,先進(jìn)后出。
Push(object var): //進(jìn)棧
??????? object Pop() : //出棧
??????? object Peek(): //返回棧頂元素,但不移除
??????? 入棧和出棧都會(huì)影響Stack的元素個(gè)數(shù)。
Stack s = new Stack();
??????????? s.Push("aaa");
??????????? s.Push("bbb");
??????????? s.Push("ccc");
??????????? for (int i = 0; i < 3; i++) //這里用的是i<3而不是i<s.Count,因?yàn)镻op的過(guò)程中會(huì)影響s.Count。
??????????? {
??????????????? Console.WriteLine(s.Peek());
??????????? }
九、ListDictionary類、HybridDictionary類和StringDictionary類
??? 這三個(gè)類都實(shí)現(xiàn)了IDictionary接口,屬于System.Collections.Specialized 命名空間。
ListDictionary類對(duì)于10個(gè)或10個(gè)以下集合元素的性能非常高,但對(duì)于元素個(gè)數(shù)很大的集合性能欠佳。
HybridDictonary類在集合較小時(shí),使用 ListDictionary 來(lái)實(shí)現(xiàn) IDictionary,然后當(dāng)集合變大時(shí),切換到 Hashtable。
StringDictonary類是一個(gè)鍵和值都是強(qiáng)類型化為字符串的散列表。
??? 這三個(gè)類和Hashtable一樣,既可以用foreach進(jìn)行迭代也可以用IEnumerator進(jìn)行遍歷。??????
十、StringCollection類
??? 實(shí)現(xiàn)了IList接口,System.Collections.Specialized 命名空間。
??? 類似于只包含字符串的、強(qiáng)類型化的ArrayList。可以通過(guò)Foreach迭代,通過(guò)數(shù)字索引訪問(wèn)。
十一、NameValueCollection類
??? 類似于有序的字符串值和字符串鍵的集合,它并沒(méi)實(shí)現(xiàn)IDictionary接口。
??????? string[] AllKeys屬性:所有鍵的字符串?dāng)?shù)組。
??????? bool HasKeys():集合對(duì)象中是否包含"鍵/值"對(duì)。
??????? string Get(int index/string key):根據(jù)索引號(hào)或鍵名來(lái)取得元素的值。
??????? string GetKey(int index):根據(jù)索引號(hào)取得鍵名。
?????? 對(duì)NameValueCollection集合對(duì)象的遍歷:
NameValueCollection nvc = new NameValueCollection();
??????????? nvc.Add("a", "aaa");
??????????? nvc.Add("b","bbb");
??????????? nvc.Add("c","ccc");
??????????? foreach (string s in nvc.AllKeys)
??????????? {
??????????????? Console.WriteLine(nvc[s].ToString());
??????????? }
轉(zhuǎn)載于:https://www.cnblogs.com/ttltry-air/archive/2011/11/27/2264798.html
總結(jié)
以上是生活随笔為你收集整理的[转]迭代、集合、字典表和列表的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: C++读取INI文件
- 下一篇: 无法找到或创建字体'SansSerif'