[.net 物件導向程式設計基礎] (17) 陣列與集合
學習了前面的C#三大特性,及介面,抽象類這些相對抽象的東西以後,是不是有點很累的感覺。具體的東西總是容易理解,因此我們在介紹前面抽象概念的時候,總是舉的是具體的例項以加深理解。
本節內容相當具體,學起來也相當輕鬆。
1.陣列
1.1 什麼是陣列?
陣列是一種資料結構,包含同一個型別的多個元素。
1.2陣列的初始化
string[] mystringArray;
型別+方框號 陣列名
1.3陣列初始化
我們知道陣列是引用型別,所以需要給他分配堆上的記憶體。
1.myIntArray = new int[3];
2.myIntArray = new int[] { 1, 2, 3 };
3.int[] myIntArray = { 1, 2, 3 }; //當使用這種方法對陣列進行初始化時,只能在宣告變數陣列時使用,不能在宣告陣列之後使用。
1.4 陣列的訪問
陣列在宣告和初始化後,可以使用索引器進行訪問,索引器總是以0開頭,表示第一個元素。
//陣列呼叫 string[] stringArray = new string[] { "aa", "bb", "cc" }; Console.WriteLine("stringValue=\"{0}\"", stringArray[0]); Console.ReadLine(); //執行結果為: //stringValue="aa"
1.5陣列型別
陣列根據維度不同,分為矩陣陣列(一維陣列,二維陣列,多維陣列)和鋸齒陣列(也就是陣列的陣列),下面看一下他們的宣告方式
//陣列 宣告 string[] stringArray = new string[] { "aa", "bb", "cc" }; //陣列 訪問 Console.WriteLine("一維陣列第一個值為:{0}", stringArray[0]); //執行結果為:一維陣列第一個值為:aa //二維陣列 宣告 string[,] stringArray2 = new string[,] { { "a1", "a2", "ac" }, { "b1", "b2", "b3" }, { "c1", "c2", "c3" } }; //二維陣列訪問 Console.WriteLine("二維陣列的1維第1個值是:{0}", stringArray2[0, 0]); //執行結果為:二維陣列1維第1個值為:a1 //三維陣列訪問 宣告 int[, ,] myIntArray3 = new int[,,] { { {1,1}, {11,11}, {111,111} }, { {2,2}, {22,22}, {222,222} }, { {3,3}, {33,33}, {333,333} }, { {4,4}, {44,44}, {444,444} } }; //三維陣列訪問 訪問 Console.WriteLine("三維陣列2維的2維的第2個值為:{0}", myIntArray3[1,1, 1]); //執行結果為:三維陣列2維的2維的第2個值為:22 //鋸齒陣列(又稱陣列的陣列) int[][] myIntArray4 = new int[3][]; myIntArray4[0] = new int[] { 1, 11, 111 }; myIntArray4[1] = new int[2] { 2, 22 }; myIntArray4[2] = new int[] { 3, 33, 333, 3333 }; Console.WriteLine("鋸齒陣列第3個陣列的第2個值為:{0}", myIntArray4[2][1]); //執行結果為:鋸齒陣列第3個陣列的第2個值為:33 Console.ReadLine();
2.集合
2.1.什麼時集合?
廣義的角度理解集合,就是一組東西聚集在一起。而.NET的集合的定義為:在.NET Framework 中,提供了用於資料儲存和檢索的專用類,這些類統稱集合。這些類提供對堆疊、佇列、列表和雜湊表的支援。大多數集合類實現相同的介面。
其中最常用的是System.Collections名稱空間下的ArrayList,它是按需分配自動增加的實現IList介面的陣列。它的預設初始容量為0,因此集合的索引從0開始。
2.2.陣列和集合的區別:
在介紹集合前,先說一下集合和陣列的區別,既然有了陣列,為何C#還要設定一個集合呢?
區別如下:
陣列有他的優點,就是在記憶體中連續儲存,遍歷比較方便,也可以很方便的修改元素。缺點就是需要指定陣列變數大小,此外,兩個元素間新增一個元素也比較麻煩。
而集合則不需要事先定義大號,可以根據需要自動分配大小。隨意新增移除某一範圍元素也比較方法。
2.3 示例:
還是以前面的動物家族為例,說明集合ArrayList的插入,新增,移除操作
1 /// <summary> 2 /// 動物類(父類 抽象類) 3 /// </summary> 4 abstract class Animal 5 { 6 /// <summary> 7 /// 名字 8 /// 說明:類和子類可訪問 9 /// </summary> 10 protected string name; 11 12 /// <summary> 13 /// 建構函式 14 /// </summary> 15 /// <param name="name"></param> 16 public Animal(string name) 17 { 18 this.name = name; 19 } 20 21 private int shoutNum = 3; 22 public int ShoutNum 23 { 24 get { return shoutNum; } 25 set { shoutNum = value; } 26 } 27 28 /// <summary> 29 /// 名字(虛屬性) 30 /// </summary> 31 public virtual string MyName 32 { 33 get { return this.name; } 34 } 35 36 /// <summary> 37 /// 叫聲,這個方法去掉虛方法,把迴圈寫在這裡 38 /// </summary> 39 public void Shout() 40 { 41 string result = ""; 42 for (int i = 0; i < ShoutNum; i++) 43 result += getShoutSound() + "!"; 44 45 Console.WriteLine(MyName); 46 Console.WriteLine(result); 47 } 48 49 /// <summary> 50 /// 建立一個叫聲的虛方法,子類重寫 51 /// </summary> 52 /// <returns></returns> 53 public virtual string getShoutSound() 54 { 55 return ""; 56 } 57 } 58 /// <summary> 59 /// 狗(子類) 60 /// </summary> 61 class Dog : Animal 62 { 63 string myName; 64 public Dog(string name) 65 : base(name) 66 { 67 myName = name; 68 } 69 /// <summary> 70 /// 名字(重寫父類屬性) 71 /// </summary> 72 public override string MyName 73 { 74 get { return "我是:狗狗,我叫:" + this.name; } 75 } 76 /// <summary> 77 /// 叫(重寫父類方法) 78 /// </summary> 79 public override string getShoutSound() 80 { 81 return "汪!"; 82 } 83 } 84 85 /// <summary> 86 /// 貓(子類) 87 /// </summary> 88 class Cat : Animal 89 { 90 string myName; 91 public Cat(string name) 92 : base(name) 93 { 94 myName = name; 95 } 96 /// <summary> 97 /// 名字(重寫父類屬性) 98 /// </summary> 99 public override string MyName 100 { 101 get { return "我是:貓咪,我叫:" + this.name; } 102 } 103 /// <summary> 104 /// 叫(重寫父類方法) 105 /// </summary> 106 public override string getShoutSound() 107 { 108 return "喵!"; 109 } 110 } 111 112 /// <summary> 113 /// 羊(子類) 114 /// </summary> 115 class Sheep : Animal 116 { 117 string myName; 118 public Sheep(string name) 119 : base(name) 120 { 121 myName = name; 122 } 123 /// <summary> 124 /// 名字(重寫父類屬性) 125 /// </summary> 126 public override string MyName 127 { 128 get { return "我是:羊羊,我叫:" + this.name; } 129 } 130 /// <summary> 131 /// 叫(重寫父類方法) 132 /// </summary> 133 public override string getShoutSound() 134 { 135 return "咩!"; 136 } 137 }
呼叫及返回結果:增加、新增、移除實現示例如下:
1 //IList 新增、插入元素 2 IList animalList = new ArrayList(); 3 Cat huaHua = new Cat("花花"); 4 animalList.Insert(0, new Dog("旺財"));//Insert是在指定的索引處插入元素 5 animalList.Add(new Cat("阿狸"));//Add是在集合最後面插入元素 6 animalList.Insert(animalList.Count, new Sheep("慢羊羊")); 7 animalList.Add(huaHua); 8 //增加四個元素後的返回結果如下 9 Console.WriteLine("增加四個元素後的返回結果:"); 10 foreach (Animal animal in animalList) 11 { 12 animal.Shout(); 13 } 14 15 //移除元素 16 //旺財和阿狸退出佇列 17 animalList.RemoveAt(0); 18 animalList.RemoveAt(0);//注意這裡當移除一個元素後,後面的元素會排到第一位了,移除第二個元素不能是 animalList.RemoveAt(1); 19 animalList.Remove(huaHua);//Remove是指移除指定的元素,注意這裡不能animalList.Remove(new Cat("花花"));這樣寫查詢不到,因為new以後又是另一個例項了(另一隻同名的貓而已) 20 21 //移除元素後的返回結果如下: 22 Console.WriteLine("執行移除後的返回結果:"); 23 foreach (Animal animal in animalList) 24 { 25 animal.Shout(); 26 } 27 Console.ReadLine();
返回結果:
2.4集合ArrayList的缺點
集合ArrayList相比陣列有這麼多好處,但是他也是有很多缺點的
A.ArrayList並非型別安全
ArrayList不論什麼型別都接受,實際是接受一個object型別。
比如如下操作:
ArrayList ar = new ArrayList(); ar.Add(111); ar.Add("bbb");
我們使用foreach遍歷的時候 foreach(int array in ar){}那麼遇到”bbb”則程度報錯,因此我們說他是非安全型別。
B.遍歷ArrayList資源消耗大
因此型別的非安全,我們在使用ArrayList的時候,就意味著增加一個元素,就需要值型別轉換為Object物件。遍歷的時候,又需要將Object轉為值型別。
就是裝箱(boxing,指將值型別轉換為引用型別)和拆箱(unboxing,指將引用型別轉換為值型別)
由於裝箱了拆箱頻繁進行,需要大量計算,因此開銷很大。如此說來還不如陣列來的方便。我們只能說各有利弊,小夥伴們不要急,.net的設計者在2.0以後的版本中為我們解決了上述後顧之憂,那就是下一節要說的泛型。
3.要點:
A.陣列是一種資料結構,包含有同型別的多個元素
B..集合是.net中提供資料儲存和檢索的專用類
C.ArrayList是按需分配自動增加的實現IList介面的陣列
D.集合和陣列各有優缺點,陣列定義需要預先指定大小,而集合雖然不需要事先指定,但是存在型別安全和資源消耗過大的缺陷。
使用泛型可以解決上面的問題。
==============================================================================================
返回目錄
<如果對你有幫助,記得點一下推薦哦,有不明白的地方或寫的不對的地方,請多交流>
==============================================================================================