[.net 面向對象編程基礎] (17) 數組與集合


[.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.集合和數組各有優缺點,數組定義需要預先指定大小,而集合雖然不需要事先指定,但是存在類型安全和資源消耗過大的缺陷。

使用泛型可以解決上面的問題。

============================================================================================== 

返回目錄

 <如果對你有幫助,記得點一下推薦哦,有不明白的地方或寫的不對的地方,請多交流>
 

==============================================================================================  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM