1. 程式人生 > >C#集合詳解

C#集合詳解

以下是對最長用的集合進行簡單的總結

集合 說明
List<T> 可以像陣列一樣按索引訪問列表,但提供了其他方法來搜尋和排序
Queue<T> 先入先出資料結構,提供了方法將資料項新增到佇列的一段,從另一端刪除項,以及只檢查不刪除
Stack<T> 先入後出資料結構,提供了方法將資料壓入棧頂,從棧頂出棧,以及只檢查棧頂的項而不刪除
LinkedList<T> 雙向有序列表,為任何一端的插入和刪除進行了優化,這種集合既可作為佇列,也可作為棧,還支援列表那樣的隨機訪問
HashSet<T>
無序值列表,為快速資料獲取而優化,提供了面向集合的方法來判斷它容納的項是不是另一個HashSet<T> 物件中的項的子集,以及計算不同HashSet<T> 物件的交集和並集
Dictionary<TKey,TValue> 字典集合允許根據鍵而不是索引來獲取值
SortedList<TKey,TValue> 鍵/值對的有序列表,鍵必須實現Icomparable<T>介面

先來了解下集合的基本資訊:

1、BCL中集合型別分為泛型集合與非泛型集合。

2、非泛型集合的類和介面位於System.Collections名稱空間。

3、泛型集合的類和介面位於System.Collections.Generic名稱空間。

ICollection介面是System.Collections名稱空間中非泛型集合類的基介面,它繼承自IEnumerable介面,從IEnumerable介面繼承意味著實現該介面的實現類需要實現一個列舉器方法:GetEnumerator,該方法返回IEnumerator型別的資料。IDictionary和IList介面繼承自ICollection作為更為專用的介面,其中IDictionary介面是鍵/值對介面,它的實現如HashTable類;而IList是值的集合,其成員可通過索引訪問,如ArrayList類,次類集合與陣列相比,可以認為是可變的集合,優點有,長度自動增長等。IEnumerable和IEnumerable是所有集合或集合介面的基介面,所有集合介面或集合都繼承、實現了它。其中IEnumerable是最底層的介面。在非泛型集合裡存放的都是System.Object型別。

一、下面列出非泛型和泛型集合的介面

非泛型集合介面 泛型集合介面 說明
ICollection  ICollection<T> 定義所有集合的大小(Count),列舉器(foreach)和同步(copyto)方法,繼承自IEnumerable
IList IList<T> 表示可按照索引單獨訪問的一組物件(像陣列一樣)
IDictionary IDictionary<T> 表示鍵/值對的集合
IComparer IComparer<T> 定義型別為比較兩個物件而實現的方法
IEqualityComparer IEqualityComparer<T> 定義方法以支援物件的相等比較
IEnumerable IEnumerable<T> 公開列舉器。實現了該介面意味著允許foreach語句迴圈訪問集合中的元素
IEnumerator IEnumerator<T> 支援在泛型集合上進行簡單迭代

下面來詳細介紹各種集合介面和集合。個人認為應該從根底說起。
先抱著MSDN來說IEnumerable,擴充套件方法就不說了,擴充套件方法跳過,留到學Linq的時候再說。

1.IEnumerable介面就一個方法,沒有屬性

方法 說明
GetEnumerator 返回一個迴圈訪問集合的列舉數。 實現或繼承了該介面,就是為了這個方法,可以foreach遍歷


2、IEnumerable<T>介面也一樣,也是就一個方法,沒有屬性。

方法 說明
GetEnumerator 返回一個迴圈訪問集合的列舉數。


3、ICollection介面

方法 說明
CopyTo 從特定的 Array 索引處開始,將 ICollection 的元素複製到一個 Array 中。
GetEnumerator 返回一個迴圈訪問集合的列舉數。 (繼承自 IEnumerable。)
屬性
Count 獲取 ICollection 中包含的元素數。 原來Count的源頭在這裡。
IsSynchronized 獲取一個值,該值指示是否同步對 ICollection 的訪問(執行緒安全)。
SyncRoot 獲取可用於同步 ICollection 訪問的物件。


4、ICollection<T>

方法 說明
Count 獲取 ICollection<T> 中包含的元素數。
IsReadOnly 獲取一個值,該值指示 ICollection<T> 是否為只讀。
屬性
Add 將某項新增到 ICollection<T> 中。
Clear ICollection<T> 中移除所有項。
Contains 確定 ICollection<T> 是否包含特定值。
CopyTo 從特定的 Array 索引開始,將 ICollection<T> 的元素複製到一個 Array 中。
GetEnumerator 已過載。
Remove ICollection<T> 中移除特定物件的第一個匹配項。
這個ICollect<T>,才開始有點集合的影子了,可以Add、Clear了,怪不得它作為泛型集合介面的基類。


5、IList
IList繼承了ICollection和IEnumerable

方法 說明
Add 將某項新增到 IList 中。
Clear 從 IList 中移除所有項。
Contains 確定 IList 是否包含特定值。
CopyTo 從特定的 Array 索引處開始,將 ICollection 的元素複製到一個 Array 中。(繼承自 ICollection。)
GetEnumerator 返回一個迴圈訪問集合的列舉數。 (繼承自 IEnumerable。)
IndexOf 確定 IList 中特定項的索引。
Insert 將一個項插入指定索引處的 IList。
Remove 從 IList 中移除特定物件的第一個匹配項。
RemoveAt 移除指定索引處的 IList 項。
屬性
Count 獲取 ICollection 中包含的元素數。 (繼承自 ICollection。)
IsFixedSize 獲取一個值,該值指示 IList 是否具有固定大小。
IsReadOnly 獲取一個值,該值指示 IList 是否為只讀。
IsSynchronized 獲取一個值,該值指示是否同步對 ICollection 的訪問(執行緒安全)。 (繼承自 ICollection。)
Item 獲取或設定指定索引處的元素。
SyncRoot 獲取可用於同步 ICollection 訪問的物件。 (繼承自 ICollection。)
可以看到,在不斷的繼承過程中,這些介面不斷地新增自己的東西,越繼承越多,越繼承越多


6、IList<T>
IList<T>繼承了ICollection<T>,IEnumerable<T>,IEnumerable

方法 說明
Add 將某項新增到 ICollection<(Of <(T>)>) 中。 (繼承自 ICollection<(Of <(T>)>)。)
Clear 從 ICollection<(Of <(T>)>) 中移除所有項。 (繼承自 ICollection<(Of <(T>)>)。)
Contains 確定 ICollection<(Of <(T>)>) 是否包含特定值。 (繼承自 ICollection<(Of <(T>)>)。)
CopyTo 從特定的 Array 索引開始,將 ICollection<(Of <(T>)>) 的元素複製到一個 Array 中。 (繼承自 ICollection<(Of <(T>)>)。)
GetEnumerator 已過載。
IndexOf 確定 IList<(Of <(T>)>) 中特定項的索引。
Insert 將一個項插入指定索引處的 IList<(Of <(T>)>)。
Remove 從 ICollection<(Of <(T>)>) 中移除特定物件的第一個匹配項。 (繼承自 ICollection<(Of <(T>)>)。)
RemoveAt 移除指定索引處的 IList<(Of <(T>)>) 項。
屬性
Count 獲取 ICollection<(Of <(T>)>) 中包含的元素數。 (繼承自 ICollection<(Of <(T>)>)。)
IsReadOnly 獲取一個值,該值指示 ICollection<(Of <(T>)>) 是否為只讀。 (繼承自 ICollection<(Of <(T>)>))
Item 獲取或設定指定索引處的元素。
同樣,在不斷的繼承中,增加了新的東西,功能也越來越強大,支援索引獲取和設定就是IList這個源頭的。一直弄不明白,NHibernate為什麼會選擇這個介面來返回資料,其實這個介面的東西夠用了。


7、IDictionary<TKey,TValue>介面
IDictionary<TKey,TValue>是最底層出現的鍵/值對集合了,相當於值集合中的ICollection

方法 說明
Add 已過載。
Clear 從 ICollection<(Of <(T>)>) 中移除所有項。 (繼承自 ICollection<(Of <(T>)>)。)
Contains 確定 ICollection<(Of <(T>)>) 是否包含特定值。 (繼承自 ICollection<(Of <(T>)>)。)
ContainsKey 確定 IDictionary<(Of <(TKey, TValue>)>) 是否包含具有指定鍵的元素。
CopyTo 從特定的 Array 索引開始,將 ICollection<(Of <(T>)>) 的元素複製到一個 Array 中。 (繼承自 ICollection<(Of <(T>)>)。)
GetEnumerator 已過載。
Remove 已過載。
TryGetValue 獲取與指定的鍵相關聯的值。
屬性
Count 獲取 ICollection<(Of <(T>)>) 中包含的元素數。 (繼承自 ICollection<(Of <(T>)>)。)
IsReadOnly 獲取一個值,該值指示 ICollection<(Of <(T>)>) 是否為只讀。 (繼承自 ICollection<(Of <(T>)>)。)
Item 獲取或設定具有指定鍵的元素。
Keys 獲取包含 IDictionary<(Of <(TKey, TValue>)>) 的鍵的 ICollection<(Of <(T>)>)。
Values 獲取包含 IDictionary<(Of <(TKey, TValue>)>) 中的值的 ICollection<(Of <(T>)>)。
該介面提供的功能和ICollection差不多,其實就是鍵/值對的開宗立派者。


8、IDictionary

方法 說明
Add 在 IDictionary 物件中新增一個帶有所提供的鍵和值的元素。
Clear 從 IDictionary 物件中移除所有元素。
Contains 確定 IDictionary 物件是否包含具有指定鍵的元素。
CopyTo 從特定的 Array 索引處開始,將 ICollection 的元素複製到一個 Array 中。 (繼承自 ICollection。)
GetEnumerator 已過載。
Remove 從 IDictionary 物件中移除帶有指定鍵的元素。
屬性
Count 獲取 ICollection 中包含的元素數。 (繼承自 ICollection。)
IsFixedSize 獲取一個值,該值指示 IDictionary 物件是否具有固定大小。
IsReadOnly 獲取一個值,該值指示 IDictionary 物件是否為只讀。
IsSynchronized 獲取一個值,該值指示是否同步對 ICollection 的訪問(執行緒安全)。 (繼承自 ICollection。)
Item 獲取或設定具有指定鍵的元素。
Keys 獲取 ICollection 物件,它包含 IDictionary 物件的鍵。
SyncRoot 獲取可用於同步 ICollection 訪問的物件。 (繼承自 ICollection。)
Values 獲取 ICollection 物件,它包含 IDictionary 物件中的值。


9、ISet<T>
Set<T>同樣是繼承自ICollection<T>,IEnumerable<T>,IEnumerable

方法 說明
Add(T) 將某項新增到 ICollection 中。 (繼承自 ICollection。)
Add(T) 向當前集內新增元素,並返回一個指示是否已成功新增元素的值。
Clear 從 ICollection 中移除所有項。 (繼承自 ICollection。)
Contains 確定 ICollection 是否包含特定值。 (繼承自 ICollection。)
CopyTo 從特定的 Array 索引開始,將 ICollection 的元素複製到一個 Array 中。 (繼承自 ICollection。)
ExceptWith 從當前集內移除指定集合中的所有元素。
GetEnumerator() 返回一個迴圈訪問集合的列舉數。 (繼承自 IEnumerable。)
GetEnumerator() 返回一個迴圈訪問集合的列舉器。 (繼承自 IEnumerable。)
IntersectWith 修改當前集,使該集僅包含指定集合中也存在的元素。
IsProperSubsetOf 確定當前的設定是否正確 (嚴格) 指定集合的子集。
IsProperSupersetOf 確定當前的設定是否正確 (嚴格) 指定集合中的超集。
IsSubsetOf 確定一個集是否為指定集合的子集。
IsSupersetOf 確定當前集是否為指定集合的超集。
Overlaps 確定當前集是否與指定的集合重疊。
Remove 從 ICollection 中移除特定物件的第一個匹配項。 (繼承自 ICollection。)
SetEquals 確定當前集與指定的集合中是否包含相同的元素。
SymmetricExceptWith 修改當前集,使該集僅包含當前集或指定集合中存在的元素(但不可包含兩者共有的元素)。
UnionWith 修改當前設定,以使其包含當前集或指定的集合中的所有元素。

先說IComparer介面,這個介面就一個方法,用於如何比較兩個物件

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);
            }
        }
    }

說完了集合介面,現在開始說集合。
1、ArrayList
  ArrayList實現了IList、ICollection、IEnumerable介面。
  ArrayList與Array的名字很相似,現在來比較一下兩者的異同。
  相同點:
  (1)、兩者都實現了IList、ICollection、IEnumerable介面。
  (2)、兩者都可以使用整數索引訪問集合中的元素,包括讀取和賦值,且集合中的索引都從0開始。
  不同點:
  (1)、ArrayList是集合,而Array是陣列。
  (2)、ArrayList是具體類,Array是抽象類。
 (3)、陣列必須在例項化時指定元素的數量,該數量一旦確定就不可以更改了,而ArrayList擴充套件了這一點,當例項化一個ArrayList例項時可以不指定集合元素數(有預設初始容量),當然你也可以指定初始容量。
  (4)、獲取陣列的元素數時使用Length屬性,而獲取ArrayList集合的元素數時使用Count屬性。
  (5)、陣列可以有多維,而ArrayList只能是一維。

屬性 說明
Capacity 獲取或設定 ArrayList 可包含的元素數。
Count 獲取 ArrayList 中實際包含的元素數。
IsFixedSize 獲取一個值,該值指示 ArrayList 是否具有固定大小。
IsReadOnly 獲取一個值,該值指示 ArrayList 是否為只讀。
IsSynchronized 獲取一個值,該值指示是否同步對 ArrayList 的訪問(執行緒安全)。
Item 獲取或設定指定索引處的元素。
SyncRoot 獲取可用於同步 ArrayList 訪問的物件。
方法
Adapter 為特定的 IList 建立 ArrayList 包裝。
Add 將物件新增到 ArrayList 的結尾處。
AddRange 將 ICollection 的元素新增到 ArrayList 的末尾。
BinarySearch 已過載。 使用對分檢索演算法在已排序的 ArrayList 或它的一部分中查詢特定元素。
Clear 從 ArrayList 中移除所有元素。
Clone 建立 ArrayList 的淺表副本。
Contains 確定某元素是否在 ArrayList 中。
CopyTo 已過載。 將 ArrayList 或它的一部分複製到一維陣列中。
FixedSize 已過載。 返回具有固定大小的列表包裝,其中的元素允許修改,但不允許新增或移除。
GetEnumerator 已過載。 返回迴圈訪問 ArrayList 的列舉數。
GetRange 返回 ArrayList,它表示源 ArrayList 中元素的子集。
IndexOf 已過載。 返回 ArrayList 或它的一部分中某個值的第一個匹配項的從零開始的索引。
Insert 將元素插入 ArrayList 的指定索引處。 可在任意位置插入。
InsertRange 將集合中的某個元素插入 ArrayList 的指定索引處。
LastIndexOf 已過載。 返回 ArrayList 或它的一部分中某個值的最後一個匹配項的從零開始的索引。
ReadOnly 已過載。 返回只讀的列表包裝。
Remove 從 ArrayList 中移除特定物件的第一個匹配項。
RemoveAt 移除 ArrayList 的指定索引處的元素。
RemoveRange 從 ArrayList 中移除一定範圍的元素。
Repeat 返回 ArrayList,它的元素是指定值的副本。
Reverse 已過載。 將 ArrayList 或它的一部分中元素的順序反轉。
SetRange 將集合中的元素複製到 ArrayList 中一定範圍的元素上。
Sort 已過載。 對 ArrayList 或它的一部分中的元素進行排序。
Synchronized 已過載。 返回同步的(執行緒安全)列表包裝。
ToArray 已過載。 將 ArrayList 的元素複製到新陣列中。
TrimToSize 將容量設定為 ArrayList 中元素的實際數目。
 static void Main(string[] args)
        {

            ArrayList arrayList = new ArrayList();
            arrayList.Add(1);                       //Add方法,將一個元素新增到ArrayList中
            arrayList.Add("你好");
            arrayList.Add(3.265);
            IList iList = arrayList;
            ICollection iCollection = iList;
            IEnumerable iEnumerable = iCollection;  //體現了ArrayList的繼承關係
            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] = "我是用來佔位的";
            arrayList.CopyTo(objArr, 1); //便宜一位,也就是接受陣列從1開始,預設是0
            foreach (object obj in objArr)
            {
                Console.Write(obj.ToString() + "-");    //輸出 我是用來佔位的-1-你好-3.265-
            }
            Console.WriteLine();

            ArrayList AL = ArrayList.FixedSize(arrayList);  //靜態方法 返回一個固定大小的ArrayList物件,數量不許改變。也就是說不能新增和刪除。
            Console.WriteLine(AL.IsFixedSize);  //輸出True
            //AL.Add(111); 此處報異常,"集合的大小是固定的"
            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);   //從左邊開始檢索,返回第一個匹配到的元素的順序
            Console.WriteLine(indexLocation);   //輸出  0

            arrayList.Add(1);       //為了體現LastIndexOf的不同,先新增一個1
            int lastLocation = arrayList.LastIndexOf(1);
            Console.WriteLine(lastLocation);    //返回3

            arrayList.Insert(2, "Insert插入的元素");  //這個方法與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可以看到將一個新的集合追加到了最後
            }

            arrayList.Remove(2);
            foreach (object obj in arrayList)
            {
                Console.Write(obj.ToString() + "-");    //輸出 1 你好 Insert插入的元素 3.265 1 1 可以看到2已經被移除了
            }
            Console.WriteLine();

            arrayList.RemoveAt(0);
            foreach (object obj in arrayList)
            {
                Console.Write(obj.ToString() + "-");    //輸出 你好 Insert插入的元素 3.265 1 1 可以看到第0個元素"2"已經被移除了
            }
            Console.WriteLine();

            //arrayList.Reverse();
            //foreach (object obj in arrayList)
            //{
            //    Console.Write(obj.ToString() + "-");        //輸出順序倒轉的所有元素
            //}

            ArrayList AL3 = new ArrayList();
            arrayList.SetRange(0,AL3);      //從第0位開始,將元素複製到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;     //讀取或設定可包含元素的數量,如果小於當前會報錯。
            Console.WriteLine(arrayList.Count);     //輸出5   
            arrayList.TrimToSize();
            Console.WriteLine(arrayList.Count);     //輸出5  

            Console.ReadKey();
        }

2、非泛型集合HashTable
  Hashtable實現了IDictionary、ICollection以及IEnumerable介面。注意Hashtable,t是小寫的。由於是非泛型集合,因此儲存進去的都是object型別,不管是鍵還是值。
  Hashtable的要點。
  (1)、Hashtable僅有非泛型版本。
  (2)、Hashtable類中的鍵不允許重複,但值可以。
  (3)、Hashtable類所儲存的鍵值對中,值可以為null,但鍵不允許為null。
  (4)、Hashtable不允許排序操作。
  以下給出一個例項,Hashtable提供的功能是在於ArraryList差不多,只不過儲存的是鍵值對而已。只寫個基本短小的示例。
  
C#中HashTable的用法

 static void Main(string[] args)
        {
            Hashtable ht = new Hashtable();
            ht.Add(1,1);
            ht.Add("我愛你","是嗎?");
            Console.WriteLine(ht.Count);    //輸出 2
            Console.WriteLine(ht["我愛你"]);   //輸出 "是嗎?"  用鍵 獲取值
            Console.WriteLine(ht.Contains(1));  //輸出True

            Console.ReadKey();
        }

3、QueueQueue<T>
  Queue成為佇列,佇列是這樣一種資料結構,資料有列表的一端插入,並由列表的另一端移除。就像單行道,只能從一段進,從一端出。Queue類實現了ICollection和IEnumerable介面。
  Queue的一些重要特性。
  1、先進先出
  2、可以新增null值到集合中
  3、允許集合中的元素重複
  4、Queue容量會按需自動新增
  5、Queue的等比因子是當需要更大容量時當前容量要乘以的數字,預設是2.0。

成員 型別 說明
Clear 方法 從Queue中移除所有物件,清空佇列。
Contains 方法 確定某元素是否在Queue中
Enqueue 方法 將物件新增到Queue的結尾處入列
Dequeue 方法 移除並返回位於Queue開始處的物件出列
Peek 方法 返回位於Queue開始出的物件,但不將其移除,與出列不同,出列是會移除的

提供的功能都是差不多的,現在給出一個例項,主要顯示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;            //出隊的時候q.Count在變化,因此q.Count放在迴圈條件裡是不妥的
            for (int i = 0; i < Count; i++)
            {
                Console.WriteLine(q.Dequeue().ToString());  //注意 輸出 1 想家了 1.23  都是從最先新增的先拿
            }
            Console.WriteLine(q.Count); //輸出0 出列一次,就自動移除了。

            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 出列一次,就自動移除了。

            Console.ReadKey();
        }

4、Stack和Stack<T>
  Stack稱為棧,棧和佇列非常相似,只不過佇列是先進先出,而棧中的資料新增和移除都在一端進行,遵守棧中的資料則後進先出。Stack類實現了ICollection和IEnumerable介面。
  Stack類的一些重要特性如下:
  1、後進先出。
  2、可以新增null值到集合中。
  3、允許集合中的元素重複。
  4、Stack的容量會按需自動增加。
  
列出幾個有特點的功能:

成員 型別 說明
Clear 方法 從Stack中移除所有物件
Contains 方法 確定某元素是否在Stack中
Push 方法 將物件插入Stack的頂部入棧
Pop 方法 移除並返回Stack頂部的物件 出棧
Peek 方法 返回位於Stack頂部的物件,但不移除,注意出棧是移除的。它不移除僅僅返回。
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;    //差點犯了邏輯錯誤,在for裡面如果是s.Count的話,很容易亂,因為出棧操作s.Count是在變動著的。
            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;    //差點犯了邏輯錯誤,在for裡面如果是s.Count的話,很容易亂,因為出棧操作s.Count是在變動著的。
            for (int i = 0; i < IntCount; i++)
            {
                Console.WriteLine(sInt.Pop());     //輸出 3 2 1
            }
            Console.WriteLine(sInt.Count);     //輸出0


            Console.ReadKey();
        }

5、SortedListSortedList<T>
  SortedList類實現了IDictionary、ICollection以及IEnumerable介面。SortedList類與HashTable類似,也表示一個鍵/值對集合,可以通過鍵和索引對元素進行訪問,但不同的是,也是該類的最大作用所在,就是支援基於鍵的排序。在SortedList中,鍵和值分別儲存在一個數組中,當向Sorted新增一個元素時,SortedList類新增一個元素時,SortedList會首先對key進行排序,然後根據排序結果計算出要插入到集合中的位置索引,再分別將key和value插入到各自陣列的指定索引位置。當使用foreach迴圈集合中的元素時,SortedList會將相同索引位置的key和value放進一個DictionaryEntry型別的物件,然後返回。
C#集合之SortedList  

static void Main(string[] args)
        {
            SortedList SL = new SortedList();
            SL.Add("txt","txt");                    //Add的時候會自動排序
            SL.Add("jpg","jpg");
            SL.Add("png","png");
            foreach (DictionaryEntry de in SL)      //返回的是DictionaryEntry物件
            {
                Console.Write(de.Key + ":" + de.Value + "  ");  //輸出 jpg:jpg png:png txt:txt    //注意這個順序啊,新增的時候就自動排序了
            }

            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,在學習的時候儘量少用var,起碼要知道返回的是什麼
            {
                Console.Write(des.Key + ":" + des.Value + " ");
            }

            Console.ReadKey();
        }

6、BitArray
  BitArray類實現了一個位結構,它是一個二進位制位(0和1)的集合。BitArray的值表示true或false。true表示位開啟,false表示位關閉。BitArray實現了ICollection和IEnumerable介面。
  BitArray的一些特性如下:
  1、BitArray集合不支援動態調整,因此沒有Add和Remove方法。
  2、若需要調整集合的大小,可通過設定屬性Length的值來實現。
  3、集合中的索引從0開始。
  4、使用BitArray(int length)建構函式初始化BitArray集合後,其值均為false。
  5、BitArray集合之間支援按位“或”、“異或”、“與運算”,參與這三類運算的BitArray集合長度必須相等。否則會丟擲異常。

成員 說明
Count 獲取 BitArray 中包含的元素數。
IsReadOnly 獲取一個值,該值指示 BitArray 是否為只讀。
IsSynchronized 獲取一個值,該值指示是否同步對 BitArray 的訪問(執行緒安全)。
Item 獲取或設定 BitArray 中特定位置的位的值。
Length 獲取或設定 BitArray 中元素的數目。
SyncRoot 獲取可用於同步 BitArray 訪問的物件。
方法 說明
And 對當前 BitArray 中的元素和指定的 BitArray 中的相應元素執行按位 AND 運算。
Clone 建立 BitArray 的淺表副本。
CopyTo 從目標陣列的指定索引處開始將整個 BitArray 複製到相容的一維 Array。
Get 獲取 BitArray 中特定位置處的位的值。
GetEnumerator 返回迴圈訪問 BitArray 的列舉數。
Not 反轉當前 BitArray 中的所有位值,以便將設定為 true 的元素更改為 false;將設定為 false 的元素更改為 true。
Or 對當前 BitArray 中的元素和指定的 BitArray 中的相應元素執行按位“或”運算。
Set 將 BitArray 中特定位置處的位設定為指定值。
SetAll 將 BitArray 中的所有位設定為指定值。
Xor 對當前 BitArray 中的元素和指定的 BitArray 中的相應元素執行按位“異或”運算。
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); //與運算,返回一個新的BitArray
            foreach (var b in BOr)
            {
                Console.Write(b + "-");     //True-False-True
            }

            Console.ReadKey();
        }

7、Dictionary 字典

方法 說明
Add 將指定的鍵和值新增到字典中
Clear Dictionary<TKey, TValue> 中移除所有的鍵和值。
ContainsKey 確定 Dictionary<TKey, TValue> 是否包含指定的鍵。
ContainsValue 確定 Dictionary<TKey, TValue> 是否包含特定值。
Equals(Object) 確定指定的 Object 是否等於當前的 Object。 (繼承自 Object。)
Finalize 允許物件在“垃圾回收”回收之前嘗試釋放資源並執行其他清理操作。 (繼承自 Object。)
GetEnumerator 返回迴圈訪問 Dictionary<TKey, TValue> 的列舉器。
GetHashCode 用作特定型別的雜湊函式。 (繼承自 Object。)
GetObjectData 實現 System.Runtime.Serialization.ISerializable 介面,並返回序列化 Dictionary 例項所需的資料。
GetType 獲取當前例項的 Type。 (繼承自 Object。)
MemberwiseClone 建立當前 Object 的淺表副本。 (繼承自 Object。)
OnDeserialization 實現 System.Runtime.Serialization.ISerializable 介面,並在完成反序列化之後引發反序列化事件。
Remove Dictionary<TKey, TValue> 中移除所指定的鍵的值。
ToString 返回表示當前物件的字串。 (繼承自 Object。)
TryGetValue 獲取與指定的鍵相關聯的值。
屬性
Comparer 獲取用於確定字典中的鍵是否相等的 IEqualityComparer<T>
Count 獲取包含在 Dictionary<TKey, TValue> 中的鍵/值對的數目。
Item 獲取或設定與指定的鍵相關聯的值。
Keys 獲取包含 Dictionary<TKey, TValue> 中的鍵的集合。
Values 獲取包含 Dictionary<TKey, TValue> 中的值的集合。
    //定義
    Dictionary<string, string> openWith = new Dictionary<string, string>();

    //新增元素
    openWith.Add("txt", "notepad.exe");
    openWith.Add("bmp", "paint.exe");
    openWith.Add("dib", "paint.exe");
    openWith.Add("rtf", "wordpad.exe");

    //取值
    Console.WriteLine("For key = \"rtf\", value = {0}.", openWith["rtf"]);

     //更改值
    openWith["rtf"] = "winword.exe";
    Console.WriteLine("For key = \"rtf\", value = {0}.", openWith["rtf"]);

    //遍歷key
    foreach (string key in openWith.Keys)
    {
        Console.WriteLine("Key = {0}", key);
    }

    //遍歷value
    foreach (string value in openWith.Values)
    {
        Console.WriteLine("value = {0}", value);
    }

    //遍歷value, Second Method
    Dictionary<string, string>.ValueCollection valueColl = openWith.Values;
    foreach (string s in valueColl)
    {
        Console.WriteLine("Second Method, Value = {0}", s);
    }

//遍歷字典
    foreach (KeyValuePair<string, string> kvp in openWith)
    {
        Console.WriteLine("Key = {0}, Value = {1}", kvp.Key, kvp.Value);
    }

    //新增存在的元素
    try
    {
        openWith.Add("txt", "winword.exe");
    }
    catch (ArgumentException)
    {
        Console.WriteLine("An element with Key = \"txt\" already exists.");
    }

    //刪除元素
    openWith.Remove("doc");
    if (!openWith.ContainsKey("doc"))
    {
        Console.WriteLine("Key \"doc\" is not found.");
    }

    //判斷鍵存在
    if (openWith.ContainsKey("bmp")) // True 
    {
        Console.WriteLine("An element with Key = \"bmp\" exists.");
    }

    //引數為其它型別 
    Dictionary<int, string[]> OtherType = new Dictionary<int, string[]>();
    OtherType.Add(1, "1,11,111".Split(','));
    OtherType.Add(2, "2,22,222".Split(','));
    Console.WriteLine(OtherType[1][2]);



    //引數為自定義型別
    //首先定義類
    class DouCube
    {
        public int Code { get { return _Code; } set { _Code = value; } } private int _Code;
        public string Page { get { return _Page; } set { _Page = value; } } private string _Page;
    } 

   //宣告並新增元素
    Dictionary<int, DouCube> MyType = new Dictionary<int, DouCube>();
    for (int i = 1; i <= 9; i++)
    {
        DouCube element = new DouCube();
        element.Code = i * 100;
        element.Page = "http://www.doucube.com/" + i.ToString() + ".html";
        MyType.Add(i, element);
    }

    //遍歷元素
    foreach (KeyValuePair<int, DouCube> kvp in MyType)
    {
        Console.WriteLine("Index {0} Code:{1} Page:{2}", kvp.Key, kvp.Value.Code, kvp.Value.Page);
    }