c#基礎語言編程-集合

引言

在c#常用的集合分爲非泛型集合和泛型集合。
非泛型集合的類和接口位於System.Collections命名空間。這些接口和類定義各種對象(如列表、隊列、位數組、哈希表和字典)的集合。
泛型集合的類和接口位於System.Collections.Generic命名空間。命名空間包含定義泛型集合的接口和類,泛型集合允許用戶創建強類型集合,它能提供比非泛型強類型集合更好的類型安全性和性能。
System.Collections.Specialized 命名空間包含專用的和強類型的集合,例如,鏈接的列表詞典、位向量以及只包含字符串的集合。
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只能是一維。

來看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 中元素的實際數目。

要知道,集合中有兩個屬性,其一是該集合的容量Capacity,其二是集合中擁有元素的個數Count。這兩者並不對等的。集合的容量是表示該集合中能容納的元素個數;而集合中擁有元素的個數是表示添加到該集合中的元素個數。Capacity的值始終大於或等於Count的值。

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不允許排序操作。
3、Queue和Queue

  Queue成爲隊列,隊列是這樣一種數據結構,數據有列表的一端插入,並由列表的另一端移除。就像單行道,只能從一段進,從一端出。Queue類實現了ICollection和IEnumerable接口。

  Queue的一些重要特性。

  1、先進先出

  2、可以添加null值到集合中

  3、允許集合中的元素重複

  4、Queue容量會按需自動添加

  5、Queue的等比因子是當需要更大容量時當前容量要乘以的數字,默認是2.0。

  現在列出Queue一個特性的功能

成員       類型        說明

Clear       方法        從Queue中移除所有對象,清空隊列。

Contains     方法        確定某元素是否在Queue中

Enqueue     方法        將對象添加到Queue的結尾處  入列

Dequeue     方法        移除並返回位於Queue開始處的對象  出列

Peek       方法        返回位於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

  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、SortedList與SortedList

  SortedList類實現了IDictionary、ICollection以及IEnumerable接口。SortedList類與HashTable類似,也表示一個鍵/值對集合,可以通過鍵和索引對元素進行訪問,但不同的是,也是該類的最大作用所在,就是支持基於鍵的排序。在SortedList中,鍵和值分別保存在一個數組中,當向Sorted添加一個元素時,SortedList類添加一個元素時,SortedList會首先對key進行排序,然後根據排序結果計算出要插入到集合中的位置索引,再分別將key和value插入到各自數組的指定索引位置。當使用foreach循環集合中的元素時,SortedList會將相同索引位置的key和value放進一個DictionaryEntry類型的對象,然後返回。
  

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、List
List是ArrayList的泛型等效版本,兩者功能相似。它實現了6個接口,實際上市對應的3對。

1、IEnumerable和IEnumerable

2、ICollection和ICollection

3、IList和IList

  使用List有很多好處。比如類型安全和可以存儲引用類型以及值類型的數據,避免了使用ArrayList存儲值類型數據時的裝箱拆箱操作。以及在存儲引用類型時的顯示類型轉化難操作,有一定的性能優勢。

  List類的一些重要特性如下:

  1、可以添加null值到集合中。

  2、允許集合中的元素重複。

  3、可以使用整數索引訪問此集合中的元素,索引從零開始。

  在創建List的對象時,沒有指定List列表的容量大小,則默認的容量大小是零,但是一旦有數據加入到列表,則列表的容量就會擴展到4;第5個加入時就會擴展到8;第9個加入就擴展到16,如此類推。列表容量總是成倍地增長。擴展時需要重新申請內存,這樣會影響效率,如果事先知道元素的數目,或者可能的數目(儘量大的估算),建議使用一個初始化容量來實例化List對象。

  構造方法:

  1、List();  使用默認的初始容量初始化一個空的實例。

  2、List(IEnumerable collection)  創建一個實例,並從指定的集合中複製元素到新實例中。

  3、List(Int32)  使用指定的容量初始化一個空的實例。

  屬性              說明

  Capacity             獲取或設置該內部數據結構在不調整大小的情況下能夠容納的元素總數。
  Count              獲取 List<(Of <(T>)>) 中實際包含的元素數。
  Item               獲取或設置指定索引處的元素。

  方法

Add                將對象添加到 List<(Of <(T>)>) 的結尾處。
AddRange             將指定集合的元素添加到 List<(Of <(T>)>) 的末尾。
AsReadOnly            返回當前集合的只讀 IList<(Of <(T>)>) 包裝。
BinarySearch           已重載。 使用對分檢索算法在已排序的 List<(Of <(T>)>) 或它的一部分中查找特定元素。
Clear               從 List<(Of <(T>)>) 中移除所有元素。
Contains             確定某元素是否在 List<(Of <(T>)>) 中。
ConvertAll<(Of <(TOutput>)>) 將當前 List<(Of <(T>)>) 中的元素轉換爲另一種類型,並返回包含轉換後的元素的列表。
CopyTo              已重載。 將 List<(Of <(T>)>) 或它的一部分複製到一個數組中。
Exists              確定 List<(Of <(T>)>) 是否包含與指定謂詞所定義的條件相匹配的元素。
Find               搜索與指定謂詞所定義的條件相匹配的元素,並返回整個 List<(Of <(T>)>) 中的第一個匹配元素。
FindAll              檢索與指定謂詞定義的條件匹配的所有元素。
FindIndex             已重載。 搜索與指定謂詞所定義的條件相匹配的元素,返回 List<(Of <(T>)>) 或它的一部分中第一個匹配項的從零開始的索引。
FindLast             搜索與指定謂詞所定義的條件相匹配的元素,並返回整個 List<(Of <(T>)>) 中的最後一個匹配元素。
FindLastIndex          已重載。 搜索與指定謂詞所定義的條件相匹配的元素,返回 List<(Of <(T>)>) 或它的一部分中最後一個匹配項的從零開始的索引。
ForEach             對 List<(Of <(T>)>) 的每個元素執行指定操作。
GetEnumerator          返回循環訪問 List<(Of <(T>)>) 的枚舉數。
GetRange            創建源 List<(Of <(T>)>) 中的元素範圍的淺表副本。
IndexOf             已重載。 返回 List<(Of <(T>)>) 或它的一部分中某個值的第一個匹配項的從零開始的索引。
Insert              將元素插入 List<(Of <(T>)>) 的指定索引處。
InsertRange           將集合中的某個元素插入 List<(Of <(T>)>) 的指定索引處。
LastIndexOf           已重載。 返回 List<(Of <(T>)>) 或它的一部分中某個值的最後一個匹配項的從零開始的索引。
Remove             從 List<(Of <(T>)>) 中移除特定對象的第一個匹配項。
RemoveAll            移除與指定的謂詞所定義的條件相匹配的所有元素。
RemoveAt            移除 List<(Of <(T>)>) 的指定索引處的元素。
RemoveRange          從 List<(Of <(T>)>) 中移除一定範圍的元素。
Reverse             已重載。 將 List<(Of <(T>)>) 或它的一部分中元素的順序反轉。
Sort               已重載。 對 List<(Of <(T>)>) 或它的一部分中的元素進行排序。
ToArray             將 List<(Of <(T>)>) 的元素複製到新數組中。
TrimExcess            將容量設置爲 List<(Of <(T>)>) 中的實際元素數目(如果該數目小於某個閾值)。
TrueForAll            確定是否 List<(Of <(T>)>) 中的每個元素都與指定的謂詞所定義的條件相匹配。

7、HashSet
類主要是設計用來做高性能集運算的,例如對兩個集合求交集、並集、差集等。集合中包含一組不重複出現且無特性順序的元素。

HashSet的一些特性如下:

1、HashSet中的值不能重複且沒有順序。

2、HashSet的容量會按需自動添加。

構造方法:

HashSet() 默認相等比較器創建一個空的新實例。

HashSet(IEnumerable collection)  把指定集合中的collection中的數據複製到集中

HashSet(IEqualityComparer comparer)  使用指定的相等比較器創建一個空的新實例

HashSet(IEnumerable collection,IEqualityComparer comparer)  使用指定的比較器實例化數據,且將指定集合中的元素複製到集合中。

因爲HashSet是專門設計來做集合運算的,因此它提供的方法中有不少是和集合運算相關的。

以下給出它的一些常用方法介紹

成員        類型        說明

Add        方法        將指定的元素添加到集合中

Clear        方法         清空集合中的所有元素

Contains     方法         確定某元素是否在HashSet中

Exists       方法         確定HashSet是否包含於指定條件相匹配的元素

ExceptWith    方法         從當前HashSet移除指定集合中的所有元素

IntersectWith   方法        修改當前的HashSet對象,以僅包含該對象和指定集合中存在的元素

IsProperSubsetOf  方法        確定HashSet對象是否爲指定集合的真子集

IsProperSupersetOf 方法        確定HashSet對象是否爲指定集合的真超集

IsSunsetOf     方法         確定HashSet對象是否爲指定集合的子集

IsSupersetOf    方法         確定HashSet對象是否爲指定集合的超集

Remove      方法         從HashSet對象中移除指定的元素

RemoveWhere   方法         從HashSet集合中移除與指定謂詞所定義的條件相匹配的所有元素

SetEquals     方法         確定HashSet對象與指定的集合中是否包含相同的元素

SynmmetricExceptWith  方法     修改當前的HashSet對象,以僅包含該對象或指定集合中存在的元素

TrimExcess    方法         將HashSet對象的容量設置爲它所包含的元素的實際個數,向上舍入爲接近的特性與實現的值。

UnionWith     方法         修改當前的HashSet對象,以包含該對象本身和指定集合中存在的所有元素

給個簡單的例子,寫不完的,總之記得HashSet主要的作用是用來進行,交集、並集等運算的就OK了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章