- 新手學(xué)ASP.NET 3.5網(wǎng)絡(luò)開發(fā)
- 孔琳俊 陳松等編著
- 87字
- 2018-12-27 20:32:31
5 數(shù)組和集合
上一章介紹了.NET中的字符串操作技術(shù),下面繼續(xù)介紹另一種常用的數(shù)據(jù)類型:數(shù)組和集合。同字符串一樣,數(shù)組和集合也是Web開發(fā)中最重要的類型之一,用于表示一組性質(zhì)相近的對象。
5.1 數(shù)組
數(shù)組能夠按一定規(guī)律把相關(guān)的數(shù)據(jù)組織在一起,并通過“索引”或“下標(biāo)”快速存取這些數(shù)據(jù)。本節(jié)首先介紹數(shù)組的基本概念,理解這些概念是學(xué)習(xí)使用數(shù)組的基礎(chǔ)。
5.1.1 什么是數(shù)組
【本節(jié)示例參考:\示例代碼\C05\Example_Array】
數(shù)組即一組數(shù)據(jù),它把一系列數(shù)據(jù)組織在一起,成為一個可操作的整體。例如,當(dāng)一個做事細(xì)心的妻子去超市買東西時,或許會事先列出一個清單:
(1)油;
(2)鹽;
(3)醬;
(4)醋;
(5)毛毛熊;
(6)……
可以稱這個清單為“需購物品”,它有規(guī)律地列出了其內(nèi)部的數(shù)據(jù),且其內(nèi)部數(shù)據(jù)具有相同的性質(zhì)。在程序語言中,可以稱這樣一個清單為數(shù)組:
//聲明數(shù)組 String[] myStrArr =new String[5]{ "油", "鹽", "醬", "醋", "毛毛熊" };
在數(shù)組中,其中的每一個元素對應(yīng)排列次序下標(biāo)。當(dāng)使用其中的某個元素時,可以直接利用這個次序下標(biāo),具體如下:
1. //輸出數(shù)組元素 2. for(int i=0;i<5;i++) 3. { 4. Page.Response.Write("myStrArr["+i+"]="+myStrArr[i]+"<br/>"); 5. }
將輸出數(shù)組myStrArr中所有的元素,如圖5.1所示。

圖5.1 輸出數(shù)組元素
說明
同C語言和大部分語言一樣,C#的下標(biāo)也是從0開始,而不是從1開始。
數(shù)組中的元素可以是任意的類型,如上面給出的示例,其中的每個元素都是字符串類型。除此之外,元素還可以是其他的基本數(shù)據(jù)類型,甚至又是一個數(shù)組。如果數(shù)組的元素又是數(shù)組,那么這個數(shù)組稱為多維數(shù)組,下面是一個二維數(shù)組的例子:
//聲明一個二維數(shù)組 String[,] myStrArr2 =new String[3,2]{ { "油", "鹽" }, { "《圍城》", "《晨露》" }, { "毛毛熊", "Snoopy" } };
在這個例子中,數(shù)組的第一維包含了三個元素,而每一個元素又是一個數(shù)組,分別包含了兩個元素。此時稱數(shù)組的秩為2;第一維的元素類型為數(shù)組,長度為3;第二維的元素類型為字符串,長度為2。
通過這個具體的例子,讀者可以思考“秩”、“維”、“元素類型”,以及“長度”的概念。同一維數(shù)組一樣,多維數(shù)組中的每一個元素,也可以通過下標(biāo)方式來引用,如:
myStrArr[0]指一維數(shù)組{“油”,“鹽”}。
myStrArr[0,0]指字符串“油”。
下面的代碼,可以輸出myStrArr2中的所有元素。
代碼5-1 輸出數(shù)組元素:Default.aspx.cs
1. //輸出二維數(shù)組元素 2. for(int i=0;i<3;i++) 3. { 4. Page.Response.Write("--myStrArr2["+i+"]<br/>"); 5. for(int j=0;j<2;j++) 6. { 7. Page.Response.Write("----myStrArr2["+i+","+j+"]="+myStrArr2[i,j]+"<br/>"); 8. } 9. }
輸出結(jié)果如圖5.2所示。

圖5.2 分層輸出二維數(shù)組
5.1.2 創(chuàng)建數(shù)組
【本節(jié)示例參考:\示例代碼\C05\Array_Create】
在C#中,使用如下語法創(chuàng)建一個數(shù)組。
1.一維數(shù)組
data type[]arr name=new data type[int length]
這種方式定義一個元素數(shù)據(jù)類型為data type、長度為length的數(shù)組arr name,例如:
int[]myIntArr=new int[100]; //定義一個長度為100的int數(shù)組 string[]mystringArr=new string[100]; //定義一個長度為100的string數(shù)組 object[]myObjectArr=new object[100]; //定義一個長度為100的object數(shù)組
其中,數(shù)據(jù)類型data type既可以是常用數(shù)據(jù)類型(如int、float等),也可以是對象(如String、StringBuilder等)。
data type[]arr name=new data type[]{item1,item2,…,itemn}
這種方式定義一個元素數(shù)據(jù)類型為data type,并通過“=”運算符進行賦值,其初始值為所給出的元素{item1,item2,…,itemn}的個數(shù),例如:
int[]myIntArr2=new int[]{1,2,3}; //定義一個int數(shù)組,長度為3 string[]mystringArr2=new string[]{"油","鹽"}; //定義一個string數(shù)組,長度為2
在這種定義下,不必給出數(shù)組的長度定義,數(shù)組的長度自動設(shè)置,為所給出的元素{item1,item2,…,itemn}的個數(shù)。即下面的兩種定義完全相同:
int[] myIntArr2=new int[]{1,2,3}; int[] myIntArr2=new int[3]{1,2,3};
2.多維數(shù)組
data type[,…,]arr name=new data type[int length1,int length2,…,int lengthn]
這種方式定義一個元素數(shù)據(jù)類型為data type,秩為n,各維長度分別為length1,length2,…,lengthn的數(shù)組arr name,例如:
int[,]myIntArr=new int[10,100]; //定義一個10*100的二維int數(shù)組 string[,,]mystringArr=new string[2,2,3]; //定義一個2*2*3的三維string數(shù)組
這里就定義了兩個多維數(shù)組。也可以用下面的方法進行多維數(shù)組的定義:
data_type[,…,] arr_name = new data_type[,…,]] { {item1, item2, … ,itemn} … }
例如:
int[,]myIntArr2=new int[,]{{1,2,3},{-1,-2,-3}}; //2*3的二維int數(shù)組 string[,]mystringArr2=new string[,]{{"油","鹽"},{"《圍城》","《晨露》"}}; //2*2的二維string數(shù)組
同一維數(shù)組一樣,在這種定義下,可以不必給出各維的長度定義,各維長度根據(jù)所給出的賦值元素自動確定。
3.交錯數(shù)組
C#支持各個維度長度不同的多維數(shù)組,稱為交錯數(shù)組,也稱為“數(shù)組的數(shù)組”。交錯數(shù)組的定義如下:
data type[][]…arr name=new data type[int length1][int length2]…
這個定義和定義多維數(shù)組非常類似,區(qū)別在于,交錯數(shù)組必須單獨初始化交錯數(shù)組每一維中的元素。例如,下面定義一個第一維長度為3的交錯數(shù)組:
1. int[][]myJaggedArray=new int[3][]; 2. myJaggedArray[0]=new int[5]; 3. myJaggedArray[1]=new int[4]; 4. myJaggedArray[2]=new int[2];
這個交錯數(shù)組myJaggedArray,每個元素都是一個一維整數(shù)數(shù)組。第一個元素是由5個整數(shù)組成的數(shù)組,第二個是由4個整數(shù)組成的數(shù)組,而第三個是由2個整數(shù)組成的數(shù)組。
data_type[][]…arr_name=new data_type[][]… { new data_type[]{item1,…,new data_type[]itemn} … }
這種方式在聲明數(shù)組的同時進行初始化,同樣可以不指定各維的長度,例如:
1. int[][]myJaggedArray=new int[][] 2. { 3. new int[]{1,3,5,7,9}, 4. new int[]{0,2,4,6}, 5. new int[]{11,22} 6. };
5.1.3 數(shù)組基類Array
System.Array類是所有.NET中數(shù)組的基類,提供創(chuàng)建、操作、搜索和排序數(shù)組的方法,其屬性和方法如圖5.3所示。

圖5.3 System.Array類
Array類常用屬性和方法的簡單說明,如表5.1所示。
表5.1 Array類常用屬性/方法說明

5.1.4 訪問數(shù)組元素
【本節(jié)示例參考:\示例代碼\C05\Array_AccessItem】
訪問數(shù)組的元素包括讀取或設(shè)置某個元素的值,最基本的方法是通過下標(biāo)定位元素,另外還可以使用GetValue/SetValue方法。
1.通過下標(biāo)定位元素
C#中數(shù)組對其中的元素進行排序,并從0開始計數(shù),這樣每一個元素都會有一個唯一的下標(biāo),通過這個下標(biāo),就可以定位唯一的一個元素。下面通過示例來說明。
(1)一維數(shù)組:
string[]myStrArr={"油", "鹽", "醬", "醋", "毛毛熊"};
這里,myStrArr[0]=“油”;myStrArr[4]=“毛毛熊”。如果試圖訪問超過下標(biāo)范圍的數(shù)據(jù),則會出現(xiàn)如下異常:
System.IndexOutOfRangeException: 索引超出了數(shù)組界限
(2)多維數(shù)組:
string[,] myStrArr2={{"油","鹽"},{"《圍城》","《晨露》"},{"毛毛熊","Snoopy"}};
定義之后,myStrArr2[0,0]=“油”;myStrArr2[2,1]=“Snoopy”。
(3)交錯數(shù)組:
1. int[][]myJaggedArray=new int[][] 2. { 3. new int[]{1,3,5,7,9}, 4. new int[]{0,2,4,6}, 5. new int[]{11,22} 6. };
定義之后則有:myJaggedArray[0][0]=1;myJaggedArray[1][1]=2;myJaggedArray[2][1]=22。
下面的代碼可以循環(huán)輸出所有的交錯數(shù)組元素。
代碼5-2 輸出交錯數(shù)組元素:Default.aspx.cs
1. for(int i=myJaggedArray.GetLowerBound(0);i<=myJaggedArray.GetUpperBound(0);i++) 2. { 3. Console.WriteLine("item{0}",i); 4. for(int j=myJaggedArray[i].GetLowerBound(0);j<=myJaggedArray[i].GetUpperBound(0);j++) 5. { 6. Console.WriteLine(" item{0}{1}:{2}",i,j,myJaggedArray[i][j]); 7. } 8. }
2.使用GetValue/SetValue
GetValue方法定義如下:
public object GetValue(params int[]indices);
其中,多個int型參數(shù)indices的含義為下標(biāo)。方法返回一個object對象,這是C#中所有對象的基類,使用多態(tài)性,它可以指向所有的C#對象。下面的代碼使用GetValue方法,循環(huán)輸出一個二維數(shù)組所有元素。
代碼5-3 使用GetValue輸出二維數(shù)組元素示例:Default.aspx.cs
1. //定義二維數(shù)組 2. string[,]myStrArr2=new string[,]{{"油","鹽"},{"《圍城》","《晨露》"},{"毛毛熊","Snoopy"}}; 3. //循環(huán)輸出 4. for(int i=myStrArr2.GetLowerBound(0);i<=myStrArr2.GetUpperBound(0);i++) 5. { 6. Console.WriteLine("item{0}",i); 7. for(int j=myStrArr2.GetLowerBound(1);j<=myStrArr2.GetUpperBound(1);j++) 8. { 9. Console.WriteLine(" item{0}{1}:{2}",i,j,myStrArr2.GetValue(i,j)); 10. } 11. }
SetValue的功能為數(shù)組的某個元素賦值,其定義及參數(shù)表同GetValue相似,不作贅述。
5.1.5 轉(zhuǎn)化元素類型
【本節(jié)示例參考:\示例代碼\C05\ Array_ConvertAll】
定義數(shù)組時,需要為其中的元素指定數(shù)據(jù)類型。有時候,在應(yīng)用中需要重新轉(zhuǎn)化元素的類型,這可以使用Array對象的CovertAll方法實現(xiàn):
public static TOutput[] ConvertAll<TInput,TOutput> (TInput[] array,Converter <TInput,TOutput> converter)
其中,類型參數(shù)TInput為源數(shù)組元素的類型,TOutput為目標(biāo)數(shù)組元素的類型。參數(shù)array為要轉(zhuǎn)換為目標(biāo)類型的從零開始的一維Array,converter為一個Converter對象,用于將每個元素從一種類型轉(zhuǎn)換為另一種類型。方法的返回值是目標(biāo)類型的數(shù)組,包含從源數(shù)組轉(zhuǎn)換而來的元素。
Convert對象表示將對象從一種類型轉(zhuǎn)換為另一種類型的方法,其定義為:
public delegate TOutput Converter<TInput,TOutput>( TInput input)
其中,類型參數(shù)TInput為要轉(zhuǎn)換的對象的類型,TOutput為要將輸入對象轉(zhuǎn)換到的類型。參數(shù)input為要轉(zhuǎn)換的對象。方法的返回值為TOutput,它表示已轉(zhuǎn)換的TInput。
下面的代碼示例將一個元素類型為int的數(shù)組轉(zhuǎn)化為string類型。
代碼5-4 使用ConvertAll轉(zhuǎn)化數(shù)據(jù)元素類型:Default.aspx.cs
1. protected void Page_Load(object sender,EventArgs e) 2. { 3. //定義一個整數(shù)類型的數(shù)組,并輸出 4. int[]src={1,2,3}; 5. Page.Response.Write("<br/>"); 6. foreach(int i in src) 7. { 8. Page.Response.Write(i+":"+i.GetType()+"<br/>"); 9. } 10. 11. //將整數(shù)數(shù)組轉(zhuǎn)化為字符串類型,并輸出 12. string[]desc=Array.ConvertAll(src, 13. new Converter<int,string>(IntToString)); 14. Page.Response.Write("<br/>"); 15. foreach(string str in desc) 16. { 17. Page.Response.Write(str+":"+str.GetType()+"<br/>"); 18. } 19. } 20. 21. ///<summary> 22. ///Converter委托 23. ///</summary> 24. ///<param name="i">整數(shù)類型的數(shù)據(jù)</param> 25. ///<returns>由輸入轉(zhuǎn)化而成的字符串類型數(shù)據(jù)</returns> 26. public static string IntToString(int i) 27. { 28. return i.ToString(); 29. }
代碼首先在第3~9行定義了一個整數(shù)類型的數(shù)組src,并輸出其中的元素和數(shù)據(jù)類型;
第11~13行利用Array類的ConvertAll方法將src轉(zhuǎn)化為字符串類型,方法的第二個參數(shù)中使用了一個委托IntToString,其實現(xiàn)在第21~29行。這個委托功能簡單,將一個輸入的整數(shù)參數(shù)轉(zhuǎn)化為字符串,并返回。
第14~19行將轉(zhuǎn)化后的字符串?dāng)?shù)組輸出。程序運行結(jié)果如圖5.4所示。

圖5.4 使用ConvertAll方法轉(zhuǎn)化數(shù)組元素類型
5.1.6 遍歷數(shù)組元素
【本節(jié)示例參考:\示例代碼\C05\ Array_Traverse】
遍歷數(shù)組是指訪問數(shù)組中的全部元素一次并且僅一次。可以在遍歷的過程中完成許多操作,如查找等。有兩種方式可以遍歷整個數(shù)組,具體如下。
1.使用GetLowerBound/GetUpperBound方法
GetLowerBound方法可以獲取數(shù)組某一維上的最低下標(biāo),而GetUpperBound則可獲取其最高下標(biāo),利用這兩個參數(shù)和for語句,可以實現(xiàn)數(shù)組的遍歷。
public int GetLowerBound (int dimension) public int GetUpperBound (int dimension)
其中,參數(shù)dimension為需要獲取上下標(biāo)的數(shù)組維度。
下面的示例實現(xiàn)了對二維數(shù)組的遍歷。
代碼5-5 利用for語句遍歷數(shù)組示例:Default.aspx.cs
1. //定義二維數(shù)組 2. string[,]myStrArr2=new string[,]{{"油","鹽"},{"《圍城》","《晨露》"},{"毛毛熊","Snoopy"}}; 3. //遍歷 4. for(int i=myStrArr2.GetLowerBound(0);i<=myStrArr2.GetUpperBound(0);i++) 5. { 6. for(int j=myStrArr2.GetLowerBound(1);j<=myStrArr2.GetUpperBound(1);j++) 7. { 8. //處理每一個元素 9. } 10. }
2.使用foreach
還可以使用更為簡便的方法來實現(xiàn)數(shù)組的遍歷,那就是foreach關(guān)鍵字,這種方法對于處理高維數(shù)組尤其方便。foreach語句格式如下:
foreach (data_typt item_name in arr_name) { //處理每一個元素 }
注意
foreach語句獲取的元素是最深層的元素,因此,無論處理幾維的數(shù)組,使用一層的foreach循環(huán)就可以了。
例如,下面的代碼實現(xiàn)同樣的二維數(shù)組遍歷。
代碼5-6 利用foreach遍歷數(shù)組示例:Default.aspx.cs
1. //定義二維數(shù)組 2. string[,]myStrArr2=new string[,]{{"油","鹽"},{"《圍城》","《晨露》"},{"毛毛熊","Snoopy"}}; 3. //遍歷 4. foreach(string item in myStrArr2) 5. { 6. { 7. //處理每一個元素 8. } 9. }
5.1.7 排序數(shù)組元素
【本節(jié)示例參考:\示例代碼\C05\ Array_Sort】
對數(shù)組進行排序是指按照一定的排序規(guī)則,如遞增或遞減規(guī)則,重新排列數(shù)組中的所有元素。可以使用Array類的Sort方法完成這個功能。Sort方法有多種重載方式,常用的形式如下:
public static void Sort(Array array);
其中,參數(shù)array為待排序的數(shù)組。下面的示例首先定義了一個數(shù)組,含有元素{5,4,3,2,1},然后利用Sort方法對其排序。
代碼5-7 利用Sort排序數(shù)組示例:Default.aspx.cs
1. ///<summary> 2. /// 利用Sort方法排序數(shù)組 3. ///</summary> 4. public void TestSort() 5. { 6. int[]myArr={5,4,3,2,1}; //定義數(shù)組 7. 8. //輸出原始數(shù)組:原始數(shù)組:5->4->3->2->1-> 9. Page.Response.Write("原始數(shù)組:"); 10. for(int i=0;i<myArr.Length;i++) 11. Page.Response.Write(myArr[i]+"->"); 12. 13. Array.Sort(myArr); //對數(shù)組排序 14. 15. Page.Response.Write("<br/>"); 16. 17. //并輸出排序后的數(shù)組:1->2->3->4->5-> 18. Page.Response.Write("排序以后數(shù)組:"); 19. for(int i=0;i<myArr.Length;i++) 20. Page.Response.Write(myArr[i]+"->"); 21. }
有時候需要進行所謂的關(guān)鍵字排序,例如,有兩個數(shù)組arrSid和arrSname,分別代表一組學(xué)生的學(xué)號和姓名,如果想要根據(jù)學(xué)號順序輸出姓名,或反之,都需要使用數(shù)組的排序操作,那么,如何把這兩個數(shù)組聯(lián)系在一起排序呢?這時就可以使用Sort的下面這種形式進行關(guān)鍵字排序。
public static void Sort(Array keys, Array items);
其中,參數(shù)keys代表關(guān)鍵字?jǐn)?shù)組,而items代表另一個數(shù)組。利用Sort,下面的代碼可實現(xiàn)上述需求。
代碼5-8 利用Sort實現(xiàn)數(shù)組多關(guān)鍵字排序示例:Default.aspx.cs
1. ///<summary> 2. /// 利用Sort實現(xiàn)數(shù)組多關(guān)鍵字排序 3. ///</summary> 4. public void TestSortMultiKey() 5. { 6. //定義數(shù)組 7. int[]arrSid={5,4,3,2,1}; 8. string[]arrSname={"張三","李四","王五","麻子","淘氣"}; 9. 10. //輸出原始數(shù)組:原始數(shù)組:張三(5)->李四(4)->王五(3)->麻子(2)->淘氣(1)-> 11. Page.Response.Write("原始數(shù)組:"); 12. for(int i=0;i<arrSid.Length;i++) 13. Page.Response.Write(arrSname[i]+"("+arrSid[i]+"->"); 14. 15. //根據(jù)學(xué)號關(guān)鍵字排序 16. Array.Sort(arrSid,arrSname); 17. Page.Response.Write("<br/>"); 18. 19. //并輸出排序后的數(shù)組:淘氣(1)->麻子(2)->王五(3)->李四(4)->張三(5) 20. Page.Response.Write("排序以后數(shù)組:"); 21. for(int i=0;i<arrSid.Length;i++) 22. Page.Response.Write(arrSname[i]+"("+arrSid[i]+"->"); 23. }
示例非常簡單,輸出已經(jīng)在注釋中給出,因此不作詳細(xì)說明。
5.1.8 查找數(shù)組元素
【本節(jié)示例參考:\示例代碼\C05\ Array_Search】
在數(shù)組中查找元素,可以有兩種解釋:一是從整個數(shù)組中尋找到與給定值相同的元素,可以使用Array類的BinarySearch方法完成這個功能;二是判斷數(shù)組中是否含有一個特定的元素,可以用Contains方法實現(xiàn)。
1.BinarySearch方法
BinarySearch使用二進制搜索算法在一維的排序Array中搜索值,注意必須是已經(jīng)排序的數(shù)組。如果找到給定的值,則返回其下標(biāo);否則,返回一個負(fù)整數(shù)。其常用形式如下:
public static int BinarySearch(Array array,object value);
其中,參數(shù)array為待搜索的數(shù)組,value為要尋找的元素值。下面的示例首先定義了一個數(shù)組,含有元素{5,4,3,2,1},然后利用BinarySearch方法返回其中的元素3的下標(biāo)(2)。
代碼5-9 利用BinarySearch搜索數(shù)組元素示例:Default.aspx.cs
1. ///<summary> 2. /// 利用BinarySearch二分搜索 3. ///</summary> 4. void TestBinarySearch() 5. { 6. //定義數(shù)組 7. int[]myArr={5,4,3,2,1}; 8. 9. //利用Sort排序 10. Array.Sort(myArr); 11. 12. //利用BinarySearch二分搜索 13. int target=3; 14. int result=Array.BinarySearch(myArr,target);//2 15. Page.Response.Write(target+"的下標(biāo)為"+result+"<br/>"); //2 16. }
2.Contains方法
Contains方法可以確定某個特定值是否包含在數(shù)組中,返回一個bool值。Array類的這個方法實際上是對IList接口中方法的實現(xiàn),其常用形式為:
bool IList.Contains(object value);
其中,參數(shù)value代表所要驗證的元素值,下面的示例判斷學(xué)生數(shù)組arrSname中是否包含“王五”。
代碼5-10 利用Contains判斷數(shù)組是否包含某個元素:Default.aspx.cs
1. ///<summary> 2. /// 利用Contains方法檢查是否包含某個元素 3. ///</summary> 4. void TestContains() 5. { 6. //定義數(shù)組 7. string[]arrSname={"張三","李四","王五","麻子","淘氣"}; 8. 9. //判斷是否含有某值 10. string target="王五"; 11. bool result=((System.Collections.IList)arrSname).Contains(target); 12. Page.Response.Write("是否包含"+target+"="+result+"<br/>"); //true 13. }
可以看到,在使用Contains方法時,需要首先將數(shù)組轉(zhuǎn)換為IList(隊列集合)對象。這是因為,本質(zhì)上,數(shù)組是一種特殊的集合對象,因此可以把它轉(zhuǎn)換為一個集合對象。對于集合,將在下一章中對其進行詳細(xì)的討論。
5.1.9 反轉(zhuǎn)數(shù)組元素
【本節(jié)示例參考:\示例代碼\C05\ Array_Reverse】
反轉(zhuǎn)數(shù)組是指將一維數(shù)組中的全部或部分元素的順序,按照其逆序重新排列。可以使用Array類的Reverse靜態(tài)方法完成這個功能。其常用的形式為:
public static int Reverse(Array array); public static int Reverse(Array array,int index, int length);
其中,參數(shù)index指定所要反轉(zhuǎn)元素的起始下標(biāo),而length指定所要反轉(zhuǎn)的元素個數(shù)。
第一個重載形式可以反轉(zhuǎn)整個數(shù)組元素,參數(shù)array為待反轉(zhuǎn)的數(shù)組。下面的示例首先定義了一個數(shù)組,含有元素{5,4,3,2,1},然后利用Reverse方法進行反轉(zhuǎn)。
代碼5-11 利用Reverse反轉(zhuǎn)數(shù)組示例:Default.aspx.cs
1. ///<summary> 2. /// 利用Reverse方法反轉(zhuǎn)數(shù)組 3. ///</summary> 4. public void TestReverse() 5. { 6. //定義數(shù)組 7. int[]myArr={5,4,3,2,1}; 8. 9. //輸出原始數(shù)組:原始數(shù)組:5->4->3->2->1-> 10. Page.Response.Write("原始數(shù)組:"); 11. for(int i=0;i<myArr.Length;i++) 12. Page.Response.Write(myArr[i]+","); 13. 14. Page.Response.Write("<br/>"); 15. 16. //對數(shù)組反轉(zhuǎn) 17. Array.Reverse(myArr); 18. 19. //并輸出反轉(zhuǎn)后的數(shù)組:1->2->3->4->5-> 20. Page.Response.Write("反轉(zhuǎn)以后數(shù)組:"); 21. for(int i=0;i<myArr.Length;i++) 22. Page.Response.Write(myArr[i]+","); 23. }
5.1.10 復(fù)制數(shù)組
【本節(jié)示例參考:\示例代碼\C05\ Array_Copy】
復(fù)制數(shù)組可以得到一個和原數(shù)組完全一樣的新數(shù)組,可以用Array的Copy或CopyTo方法來實現(xiàn)。
1.Copy方法
在使用Copy方法進行數(shù)組復(fù)制操作之前,必須首先為新的數(shù)組分配空間,然后再通過復(fù)制操作向新的數(shù)組空間中填入元素值。靜態(tài)方法Copy的常用重載形式為:
public static void Copy(Array sourceArray,Array destinationArray,int length);
其中,參數(shù)sourceArray為源數(shù)組,destinationArray為目標(biāo)數(shù)組,而length為要復(fù)制的元素數(shù)目,默認(rèn)的復(fù)制操作從第一個元素開始。下面的示例首先定義了一個數(shù)組,含有元素{5,4,3,2,1},然后利用Copy方法獲取一個新的數(shù)組,包含了源數(shù)組的前3項。
代碼5-12 利用Copy復(fù)制數(shù)組示例:Default.aspx.cs
1. ///<summary> 2. /// 利用Copy靜態(tài)方法復(fù)制數(shù)組 3. ///</summary> 4. public void TestCopy() 5. { 6. //定義數(shù)組 7. int[]myArr={5,4,3,2,1}; 8. 9. //輸出原始數(shù)組:原始數(shù)組:5,4,3,2,1, 10. Page.Response.Write("原始數(shù)組:"); 11. for(int i=0;i<myArr.Length;i++) 12. Page.Response.Write(myArr[i]+","); 13. Page.Response.Write("<br/>"); 14. 15. //復(fù)制數(shù)組 16. int[]newArr=new int[3]; 17. Array.Copy(myArr,newArr,3); 18. 19. //并輸出反復(fù)制的數(shù)組:5,4,3, 20. Page.Response.Write("復(fù)制數(shù)組:"); 21. for(int i=0;i<newArr.Length;i++) 22. Page.Response.Write(myArr[i]+","); 23. }
注意
在使用Copy進行復(fù)制數(shù)組之前,必須要首先定義一個新的數(shù)組,并對其分配空間。另外,還需保證所分配的空間足夠容納所要復(fù)制的元素。否則在復(fù)制時將出現(xiàn)異常:“System.ArgumentException:目標(biāo)數(shù)組的長度不夠”。
2.CopyTo方法
CopyTo和Copy方法的功能類似,但它是一個實例方法,即需要在數(shù)組對象上引用。另外,它只能復(fù)制源數(shù)組所有的元素,并可以控制元素在目標(biāo)數(shù)組中存放的起始位置。其常用重載形式為:
public virtual void CopyTo( Array array, int index);
其中,參數(shù)array代表所要復(fù)制的目標(biāo)數(shù)組,index則表示開始復(fù)制的元素下標(biāo)。下面的代碼實現(xiàn)對源數(shù)組的復(fù)制,并從第3個位置開始存放。
代碼5-13 利用CopyTo復(fù)制數(shù)組示例:Default.aspx.cs
1. ///<summary> 2. /// 利用CopyTo靜態(tài)方法復(fù)制數(shù)組 3. ///</summary> 4. public void TestCopyTo() 5. { 6. //定義數(shù)組 7. int[]myArr={5,4,3,2,1}; 8. 9. //輸出原始數(shù)組:原始數(shù)組:5,4,3,2,1, 10. Page.Response.Write("原始數(shù)組:"); 11. for(int i=0;i<myArr.Length;i++) 12. Page.Response.Write(myArr[i]+","); 13. Page.Response.Write("<br/>"); 14. 15. //復(fù)制數(shù)組 16. int[]newArr=new int[7]; 17. myArr.CopyTo(newArr,2); 18. 19. //并輸出復(fù)制的數(shù)組:0,0,5,4,3,2,1, 20. Page.Response.Write("復(fù)制數(shù)組:"); 21. for(int i=0;i<newArr.Length;i++) 22. Page.Response.Write(newArr[i]+","); 23. }
另外,從輸出結(jié)果還可以看到,在初始化int型數(shù)組時,其默認(rèn)值為0。
5.2 集合
上面介紹的數(shù)組常常用來實現(xiàn)靜態(tài)的操作,即不改變其空間大小,如查找、遍歷等。數(shù)組也可以實現(xiàn)動態(tài)的操作,如插入、刪除等,但不推薦使用,而應(yīng)盡量使用本節(jié)介紹的集合來代替。
5.2.1 什么是集合
集合是指一組類似的對象。在.NET中,任意類型的對象都可以放入一個集合中。.NET中的集合類存在于System.Collections命名空間中,其常用的類和結(jié)構(gòu)如圖5.5所示。

圖5.5 System.Collections命名空間常用類和結(jié)構(gòu)
從圖5.5中可以看出,System.Collections空間中的集合種類眾多,主要包括如下。
1.一般集合
一般集合是常見的集合數(shù)據(jù)結(jié)構(gòu),包括哈希表、隊列、堆棧、字典和列表等。對于這些集合的詳細(xì)含義,讀者可參考數(shù)據(jù)結(jié)構(gòu)方面的資料,本書不作詳細(xì)介紹,簡單說明如下:
(1)列表(ArrayList):一個一維的動態(tài)數(shù)組,可以裝載一組相似的數(shù)據(jù)元素。
(2)隊列(Quene):先進先出的列表。
(3)堆棧(Stack):先進后出的列表。
(4)哈希表(Hashtable):集合中的每個元素都是一個<鍵(key),值(value)>對的列表。
(5)字典(DictionaryEntry):一個<鍵(key),值(value)>對。
2.專用集合
專用集合是具有特定用途的集合,如StringCollection類,其元素只能為String對象。
3.位集合
位集合的元素為位標(biāo)志,每個元素都是一位,而不是一個對象,常用于操作數(shù)只包含1、0的集合。
5.2.2 列表類ArrayList
System.Collections.ArrayList類實現(xiàn)了可變大小的一維數(shù)組,其常用屬性和方法如圖5.6所示。

圖5.6 ArrayList類的屬性和方法
ArrayList類常用屬性和方法的簡單說明,如表5.2所示。
表5.2 ArrayList類常用屬性/方法說明

下面各節(jié),將詳細(xì)介紹其中最常用的方法。
5.2.3 創(chuàng)建列表
【本節(jié)示例參考:\示例代碼\C05\ArrayList_Create】
利用ArrayList的構(gòu)造函數(shù)來創(chuàng)建一個新的列表,常用的形式如下:
public ArrayList(); public ArrayList(int capacity);
參數(shù)capacity可以指定所創(chuàng)建列表的初始容量。如果不指定,則初始容量為.NET的默認(rèn)值16。下面的代碼創(chuàng)建了兩個列表對象:
ArrayList arr1=new ArrayList(); ArrayList arr2=new ArrayList(100);
其中,arr1的初始容量為16,arr2為100。目前,兩者里面都是空的,沒有任何元素。隨著操作的進行,當(dāng)列表中的元素達到其最大容量時,列表將自動將其容量增加1倍。另外,如果想要使用ArrayList,首先需要在代碼頭部引入命名空間:
using System.Collections;
5.2.4 遍歷列表
【本節(jié)示例參考:\示例代碼\C05\ArrayList_Traverse】
1.使用foreach語句
遍歷列表是指訪問列表中的所有元素一遍,可以使用foreach語句完成這個功能。下例使用foreach輸出列表arr1中的所有元素。
代碼5-14 使用foreach遍歷列表示例:Default.aspx.cs
1. ///<summary> 2. /// 利用Foreach語句遍歷集合 3. ///</summary> 4. void TestForeach() 5. { 6. ArrayList arr1=new ArrayList(); 7. 8. //循環(huán)添加元素0~9 9. for(int i=0;i<10;i++) 10. arr1.Add(i); 11. 12. //使用foreach遍歷數(shù)組,輸出所有元素 13. foreach(object item in arr1) 14. { 15. Page.Response.Write(item+"<br/>"); 16. } 17. }
2.使用GetEnumerator方法
除了foreach之外,還可以使用ArrayList的GetEnumerator方法實現(xiàn)列表的遍歷。其形式為:
public virtual IEnumerator GetEnumerator();
該方法返回整個ArrayList的枚舉對象IEnumerator。這個對象可以得到一個集合對象的所有元素,其最主要的屬性為Current,用于獲取集合中的當(dāng)前元素。
主要的方法包括:
MoveNext:將枚舉推進到集合的下一個元素。在傳遞到集合的末尾之后,枚舉數(shù)放在集合中最后一個元素后面,且調(diào)用MoveNext會返回false。
Reset:將枚舉設(shè)置為其初始位置,該位置位于集合中第一個元素之前。
下面的代碼使用GetEnumerator實現(xiàn)上面foreach同樣的列表遍歷功能。
代碼5-15 使用GetEnumerator遍歷列表示例:Default.aspx.cs
1. ///<summary> 2. /// 利用GetEnumerator遍歷數(shù)組 3. ///</summary> 4. void TestGetEnumerator() 5. { 6. ArrayList arr1=new ArrayList(); 7. 8. //循環(huán)添加元素0~9 9. for(int i=0;i<10;i++) 10. arr1.Add(i); 11. 12. //使用GetEnumerator遍歷數(shù)組 13. System.Collections.IEnumerator enm=arr1.GetEnumerator(); 14. while(enm.MoveNext()) 15. { 16. Page.Response.Write(enm.Current+"<br/>"); 17. } 18. }
注意
最初,枚舉數(shù)被定位于集合中第一個元素的前面。此時,調(diào)用Current會引發(fā)異常。因此在讀取Current的值之前,必須調(diào)用MoveNext將枚舉數(shù)提前到集合的第一個元素。
5.2.5 添加元素
【本節(jié)示例參考:\示例代碼\C05\ArrayList_Add】
可以通過ArrayList的Add和AddRange方法,實現(xiàn)向一個列表中添加數(shù)據(jù)。兩者的區(qū)別在于:Add一次只能添加一個元素,而AddRange一次可以添加多個元素,這多個元素需要放在一個集合或數(shù)組中。兩者常用的形式如下:
public int Add(object value); public void AddRange(ICollection c);
下面的示例中,首先定義了一個列表arr1,然后使用Add方法,向arr1中添加了兩個元素,其中第一個為字符串對象“Hello”,第二個為一個整數(shù)對象1。
然后分別定義了兩個列表arr2、arr3,并分別使用Add和AddRange方法試圖將arr1中的所有數(shù)據(jù)都添加到arr2、arr3中。從結(jié)果中可以看出,只有使用AddRange才能實現(xiàn)這個目的,而使用Add方法則可以得到一個二維數(shù)組,第一維的元素為arr1。
代碼5-16 向ArrayList中添加元素示例:Default.aspx.cs
1. ArrayList arr1=new ArrayList(); 2. 3. //向arr1中添加一個字符串對象“Hello” 4. object item=new object(); 5. item="Hello"; 6. arr1.Add(item); //arr1:{"Hello"} 7. //向arr1中添加一個整數(shù)對象1 8. item=1; 9. arr1.Add(item); //arr1:{"Hello",1} 10. 11. //向另一個列表中添加arr1中的所有元素 12. ArrayList arr2=new ArrayList(); 13. arr2.Add(arr1); //arr2只有一個元素:{arr1}={{“Hello",1}} 14. 15. ArrayList arr3=new ArrayList(); 16. arr3.AddRange(arr1); //arr3:{"Hello",1}
Add和AddRange方法只能將元素添加到列表的末尾,如果想要在列表的任意位置添加元素,則需要使用Insert方法。
5.2.6 插入元素
【本節(jié)示例參考:\示例代碼\C05\ArrayList_Insert】
如前面所述,使用ArrayList的Insert和InsertRange方法,可以實現(xiàn)向一個列表中的任意位置添加數(shù)據(jù)。這兩者的區(qū)別同Add與AddRange的區(qū)別類似,Insert一次只能添加一個元素,而InsertRange一次可以添加某個集合中的多個元素。兩者常用的形式分別如下:
public int Insert(int index, object value); public void InsertRange(int index, ICollection c);
其中,參數(shù)index指定元素所要插入的位置,從0開始索引。下面的示例中,首先定義了一個列表arr1,然后使用Add方法,向arr1中添加了兩個元素,其中第1個為字符串對象“Hello”,第2個為一個整數(shù)對象1。然后,在兩者之間插入一個整數(shù)型數(shù)組元素{1,2,3}。
代碼5-17 向ArrayList中插入元素示例:Default.aspx.cs
1. ArrayList arr1=new ArrayList(); 2. 3. //向arr1中添加一個字符串對象“Hello” 4. object item=new object(); 5. item="Hello"; 6. arr1.Add(item); //arr1:{"Hello"} 7. //向arr1中添加一個整數(shù)對象1 8. item=1; 9. arr1.Add(item); //arr1:{"Hello",1} 10. 11. //插入一個數(shù)組元素arr2 12. int[]arr2=new int[]{1,2,3}; 13. arr1.Insert(1,arr2);
使用Insert方法把arr2插入在位置1后,arr1的結(jié)果如圖5.7所示。可以看出,arr1的長度為3,下標(biāo)1處的元素為數(shù)組arr2,里面又包括了3個整數(shù)元素。

圖5.7 使用Insert后的arr1結(jié)果
如果把代碼第13行的Insert改為InsertRange,則將會把數(shù)組中的所有元素插入到arr1中,而不是數(shù)組本身,結(jié)果將如圖5.8所示。

圖5.8 使用InsertRange后的arr1結(jié)果
5.2.7 刪除元素
【本節(jié)示例參考:\示例代碼\C05\ArrayList_Delete】
ArrayList中支持刪除元素的方法分別如下:
public void Remove(object obj);
該方法用于刪除數(shù)組中特定對象obj的第一個匹配項。參數(shù)obj為要從ArrayList移除的Object。
public void RemoveAt(int index);
該方法用于移除ArrayList的指定索引處的元素。參數(shù)index為要移除的元素的從0開始的索引。
public void RemoveRange(int index,int count);
該方法用于從ArrayList中移除一定范圍的元素。參數(shù)index為要移除元素的起始索引(從0開始計數(shù)),參數(shù)count為要移除的元素數(shù)。
下面的示例中,首先定義了一個列表arr1,使用Add方法添加進10個元素(整數(shù)0~9),然后分別使用上面的3種方法,分別刪除掉元素3、元素5,以及元素{7, 8, 9}。
代碼5-18 從ArrayList中刪除元素示例:Default.aspx.cs
1. ArrayList arr1=new ArrayList(); 2. 3. //循環(huán)添加元素1~9 4. for(int i=0;i<10;i++) 5. arr1.Add(i); 6. 7. //使用Remove(),刪除掉3 8. arr1.Remove(3); 9. 10. //使用RemoveAt(),刪除掉5,注意:此時,元素5的下標(biāo)為? 11. arr1.RemoveAt(4); 12. 13. //使用RemoveRange(),一次刪除掉7、8、9,注意,元素7的下標(biāo)為? 14. arr1.RemoveRange(5,3);
5.2.8 簡單排序
【本節(jié)示例參考:\示例代碼\C05\ArrayList_SimpleSort】
對集合元素進行排序也是非常重要的操作之一,許多進一步的操作可以在排序的基礎(chǔ)上進行,例如二分查找等。ArrayList使用Sort方法來實現(xiàn)排序功能,其常用形式如下:
public virtual void Sort();
該形式可以對整個ArrayList中的元素進行排序。
下例簡單使用了無參數(shù)的Sort方法,對一個列表中的元素進行排序。這時,默認(rèn)的排序策略為非遞減排序。
代碼5-19 使用Sort方法對列表排序示例:Default.aspx.cs
1. ///<summary> 2. /// 利用Sort方法進行排序 3. ///</summary> 4. public void TestSort() 5. { 6. ArrayList arr1=new ArrayList(); 7. 8. //循環(huán)添加元素5~1 9. for(int i=5;i>0;i--) //arr1:{5,4,3,2,1} 10. arr1.Add(i); 11. 12. //使用Sort(),實現(xiàn)簡單的非遞減排序 13. arr1.Sort(); //arr1:{1,2,3,4,5} 14. }
5.2.9 復(fù)雜排序
【本節(jié)示例參考:\示例代碼\C05\ArrayList_ComplexSort】
有時需要進行更為復(fù)雜的排序操作。例如,利用逆向比較策略(即1>2策略)進行排序等。這時需要首先利用IComparer接口實現(xiàn)一個具體的比較策略,然后再利用Sort方法進行排序,所用到的Sort方法形式如下:
public virtual void Sort(IComparer comparer);
該方法使用指定的比較策略對整個ArrayList中的元素進行排序。其中,參數(shù)comparer為比較元素時要使用的比較策略,是對接口IComparer的實現(xiàn)。
下例中,首先利用IComparer接口方法,實現(xiàn)一個逆向比較策略類。IComparer中包含一個Compare接口,需要對這個接口進行實現(xiàn),返回一個整數(shù)值來表示兩個待比較對象x、y的大小關(guān)系。正數(shù)表示x>y;0表示x= =y;負(fù)數(shù)表示x<y。
代碼5-20 使用Compare方法實現(xiàn)逆比較示例:Default.aspx.cs
1. public class myReverserClass:IComparer 2. { 3. //實現(xiàn)IComparer接口的Compare方法,實現(xiàn)逆比較 4. int IComparer.Compare(Object x,Object y) 5. { 6. if(Convert.ToInt32(x)>Convert.ToInt32(y)) 7. return-1; 8. else if(Convert.ToInt32(x)==Convert.ToInt32(y)) 9. return 0; 10. else 11. return 1; 12. } 13. }
然后,便可以使用這個比較器,結(jié)合Sort方法進行逆排序,如下所示:
1. ArrayList arr1=new ArrayList(); 2. 3. //循環(huán)添加元素1~5 4. for(int i=1;i<6;i++) //arr1:{1,2,3,4,5} 5. arr1.Add(i); 6. 7. //使用逆比較策略,實現(xiàn)逆排序 8. IComparer myComparer=new myCompareReverse(); 9. arr1.Sort(myComparer); //arr1:{5,4,3,2,1}
另外,當(dāng)需要對數(shù)組中的某一部分進行排序時,可以使用Sort的如下形式:
public virtual void Sort(int index,int count,IComparer comparer);
這里使用指定的比較策略對部分ArrayList中的元素進行排序。參數(shù)index為要排序的起始索引,count為要排序的范圍的長度,comparer為比較元素時要使用的比較策略,是對接口IComparer的實現(xiàn)。
5.2.10 查找元素
【本節(jié)示例參考:\示例代碼\C05\ArrayList_Search】
在集合中對特定元素的查找也是常用的操作之一,ArrayList提供了二分查找的方法BinarySearch,可以在O(logn)時間復(fù)雜度內(nèi)完成查找,其常用形式如下:
public virtual int BinarySearch(object value);
在整個已排序的ArrayList中搜索元素,并返回該元素從0開始的索引。
代碼5-21首先使用默認(rèn)的非遞增簡單排序方法對一個列表中的元素進行排序,然后使用BinarySearch方法搜索其中的特定元素,并輸出其索引。
代碼5-21 使用BinarySearch方法查找元素示例:Default.aspx.cs
1. ArrayList arr1=new ArrayList(); 2. 3. //循環(huán)添加元素10~1 4. for(int i=0;i<10;i++) 5. arr1.Add(10-i); 6. 7. //使用BinarySearch,查找元素7,并輸出 8. arr1.Sort(); //首先需要進行排序 9. int idx=arr1.BinarySearch(7); 10. Page.Response.Write("arr["+idx+"]=7");//arr[6]=7
如果使用指定的排序策略對集合中的元素進行排序之后,相應(yīng)地,也可以使用同樣的排序策略,結(jié)合BinarySearch方法實現(xiàn)元素的查找。這時,其形式為:
public virtual int BinarySearch(object value,IComparer comparer);
此時,將使用指定的比較器在整個已排序的ArrayList中搜索元素,并返回該元素從0開始的索引。參數(shù)value為要查找的元素,而Icomparer為指定的比較策略,可參考5.2.9節(jié)相關(guān)內(nèi)容。
5.3 隊列
上一節(jié)介紹了集合中的列表類ArrayList,下面介紹一個特殊的列表——隊列。
5.3.1 什么是隊列
隊列實際上是一種特殊的列表。它對列表的操作進行了限制,要求列表中的元素必須滿足先進先出的原則,這類似于現(xiàn)實生活中的排隊,如圖5.9所示。

圖5.9 隊列示意圖
說明
隊列及后面所介紹的堆棧等,都是非常重要的數(shù)據(jù)結(jié)構(gòu),掌握它們的思想及典型應(yīng)用,在程序設(shè)計中具有重要的作用。但是,本書將不從程序設(shè)計的層次討論Queue類的應(yīng)用,而僅從集合操作的層次進行討論。如果讀者不了解數(shù)據(jù)結(jié)構(gòu)的內(nèi)容,筆者強烈建議補充一下這方面的知識。
5.3.2 隊列類Queue
Queue類常用屬性和方法如圖5.10所示。

圖5.10 Queue類的屬性和方法
Queue類最主要的方法為入隊操作Enqueue和出隊操作Dequeue,分別完成在隊列尾的添加新元素操作和在隊列頭的刪除元素操作。其他Queue支持的方法,如遍歷、清空等,和ArrayList類似,這里不作贅述。
5.3.3 創(chuàng)建隊列
【本節(jié)示例參考:\示例代碼\C05\Queue_Create】
利用Queue的構(gòu)造函數(shù)來創(chuàng)建一個新的隊列,常用的形式包括:
public Queue (); public Queue (int capacity); public Queue( int capacity, float growFactor);
參數(shù)capacity可以指定所創(chuàng)建列表的初始容量,如果不指定,則初始容量為.NET的默認(rèn)值32。而參數(shù)growFactor則指定當(dāng)隊列滿后容量的增長率,新容量等于當(dāng)前容量與growFactor的乘積,默認(rèn)值為2.0。下面的代碼創(chuàng)建了3個隊列對象:
Queue queue1=new Queue(); Queue queue2=new Queue(100); Queue queue3=new Queue(100,1.5f);
其中,queue1的初始容量為32,queue2為100。目前,兩者里面都是空的,沒有任何元素。隨著操作的進行,當(dāng)列表中的元素達到其最大容量時,列表將自動增長至200。而對于queue3,其初始容量為100,當(dāng)列表中的元素達到其最大容量時,列表將自動增長至150。
與ArrayList一樣,如果想要使用Queue,首先需要在代碼頭部引入命名空間:
using System.Collections;
5.3.4 元素入隊
【本節(jié)示例參考:\示例代碼\C05\Queue_Enqueue】
可以通過Queue的Enqueue,實現(xiàn)一個元素的入隊操作,其形式如下:
public virtual void Enqueue(object obj);
下面的示例中,首先定義了一個隊列queue1,然后使用Enqueue方法,向其中添加了3個元素,其中第1個為字符串對象“Hello”,第2個為一個整數(shù)對象1,第3個為整數(shù)型數(shù)組arr1。
代碼5-22 使用Enqueue元素入隊示例:Default.aspx.cs
1. Queue queue1=new Queue(); 2. 3. //字符串:"Hello"入隊 4. object item=new object(); 5. item="Hello"; 6. queue1.Enqueue(item); 7. //整數(shù):1入隊 8. item=1; 9. queue1.Enqueue(item); 10. //數(shù)組:arr1={1,2,3}入隊 11. int[]arr1=new int[]{1,2,3}; 12. queue1.Enqueue(arr1);
隊列中的元素如圖5.11所示。

圖5.11 隊列入隊示例
5.3.5 元素出隊
【本節(jié)示例參考:\示例代碼\C05\Queue_Dequeue】
與Enqueue相反,可以通過Queue的Dequeue實現(xiàn)一個元素的出隊操作,其形式如下:
public virtual object Dequeue();
下面的示例中,首先定義了一個隊列queue1,然后使用Enqueue方法,依次入隊3個元素。然后再使用Dequeue方法,輸出所有的元素。注意,這個輸出的順序和入隊的順序是一致的。
代碼5-23 使用Dequeue元素出隊示例:Default.aspx.cs
1. Queue queue1=new Queue(); 2. 3. //依次入隊:"Hello"、1、{1,2,3} 4. queue1.Enqueue("Hello"); 5. queue1.Enqueue(1); 6. queue1.Enqueue(new int[]{1,2,3}); 7. 8. //通過出隊操作,輸出隊列中的所有元素,這個順序,與入隊的順序一致 9. object outItem=new object(); 10. while(queue1.Count>0) 11. { 12. outItem=queue1.Dequeue(); 13. Page.Response.Write(outItem+"<br/>"); 14. }
此時,代碼輸出的結(jié)果應(yīng)與圖5.11所示相同。
5.4 堆棧
上面介紹了具有先入先出特征的隊列,下面繼續(xù)介紹另一種具有先入后出特征的集合對象:堆棧。
5.4.1 什么是堆棧
與Queue一樣,System.Collections.Stack實際上也是一種操作受限的列表,它要求列表中的元素必須滿足先進后出的原則,如圖5.12所示。

圖5.12 堆棧示意圖
5.4.2 堆棧類Stack
Stack類常用屬性和方法如圖5.13所示。其中,最主要的方法為入棧操作Push和出棧操作Pop,分別完成在堆棧的頂部添加和刪除元素的操作。其他Stack支持的方法,如遍歷、清空等,和ArrayList類似。

圖5.13 Stack類的屬性和方法
5.4.3 創(chuàng)建堆棧
【本節(jié)示例參考:\示例代碼\C05\Stack_Create】
利用Stack的構(gòu)造函數(shù)來創(chuàng)建一個新的堆棧,常用的形式包括:
public Stack (); public Stack (int capacity);
參數(shù)capacity可以指定所創(chuàng)建列表的初始容量。如果不指定,則初始容量為.NET的默認(rèn)值10。當(dāng)堆棧中的元素達到其最大容量時,其容量將自動增加一倍。下面的代碼創(chuàng)建了兩個堆棧對象:
Stack Stack1=new Stack(); Stack Stack2=new Stack(100);
其中,Stack1的初始容量為10,Stack2為100。同ArrayList、Queue一樣,如果想要使用Stack,首先需要在代碼頭部引入命名空間:
using System.Collections;
5.4.4 元素入棧
【本節(jié)示例參考:\示例代碼\C05\Stack_Push】
可以通過Stack的Push,實現(xiàn)一個元素的入棧操作,其形式如下:
public virtual void Push(object obj);
下面的示例中,首先定義了一個堆棧Stack1,然后使用Push方法,向其中添加了3個元素,其中第1個為字符串對象“Hello”,第2個為一個整數(shù)對象1,第3個為整數(shù)型數(shù)組arr1。
代碼5-24 使用Push元素入棧示例:Default.aspx.cs
1. Stack stack1=new Stack(); 2. 3. //字符串:"Hello"入棧 4. object item=new object(); 5. item="Hello"; 6. stack1.Push(item); 7. //整數(shù):1入棧 8. item=1; 9. stack1.Push(item); 10. //數(shù)組:arr1={1,2,3}入棧 11. int[]arr1=new int[]{1,2,3}; 12. stack1.Push(arr1);
堆棧中的元素是如何存放的?把堆棧假想為一個盛放油餅的框子,那么“Hello”這張餅被壓在最下面,整數(shù)1在中間,數(shù)組{1,2,3}在框子的最上面,效果如圖5.14所示。

圖5.14 堆棧出棧示例
5.4.5 元素出棧
【本節(jié)示例參考:\示例代碼\C05\Stack_Pop】
與Push相反,可以通過Stack的Pop實現(xiàn)一個元素的出棧操作,其形式如下:
public virtual object Pop();
在下面的示例中,首先定義了一個堆棧Stack1,然后使用Push方法,依次入隊3個元素。再使用Pop方法,輸出所有的元素。這個輸出的順序和入隊的順序是相反的。
代碼5-25 使用Pop元素出棧示例:Default.aspx.cs
1. Stack stack1=new Stack(); 2. 3. //依次入棧:"Hello"、1、{1,2,3} 4. stack1.Push("Hello"); 5. stack1.Push(1); 6. stack1.Push(new int[]{1,2,3}); 7. 8. //利用Pop方法,循環(huán)輸出stack1中所有的元素,注意,輸出的順序與入棧的順序是相反的 9. object outItem=new object(); 10. while(stack1.Count>0) 11. { 12. outItem=stack1.Pop(); 13. Response.Write(outItem+"<br/>"); 14. }
此時,代碼輸出的結(jié)果應(yīng)與圖5.14相同,就像從框子中把油餅逐個取出一樣。
承上啟下
■ 學(xué)完本章后,讀者需要回答:
1.什么是數(shù)組?.NET基礎(chǔ)類庫中的System.Array和數(shù)組是什么關(guān)系?
2.能夠使用數(shù)組完成以下操作。
(1)元素訪問:GetValue
(2)轉(zhuǎn)化類型:ConvertAll
(3)遍歷數(shù)組:foreach
(4)排序數(shù)組:Sort
(5)查找元素:BinarySearch/Contains
(6)反轉(zhuǎn)數(shù)組:Reverse
(7)復(fù)制數(shù)組:Copy/CopyTo
3.C#中的集合命名空間包括哪些類?
4.能夠使用ArrayList類完成以下操作。
(1)添加元素:Add/AddRange
(2)插入元素:Insert/InsertRange
(3)刪除元素:Remove/RemoveAt/RemoveRange
(4)排序元素:Sort
(5)查找元素:BinarySeach
5.Queue類和Stack類的特點是什么?如何實現(xiàn)隊列及堆棧的以下操作。
(1)入隊:Enqueue
(2)出隊:Dequeue
(3)入棧:Push
(4)出棧:Pop
■ 在下一章中,讀者將會了解:
1.利用VS.NET開發(fā)環(huán)境尋找語法錯誤和邏輯錯誤的技術(shù)。
2.利用Exception類和try-catch來捕捉程序異常的技術(shù)。
3.異常執(zhí)行的先后順序。
- Learning Java Functional Programming
- VSTO開發(fā)入門教程
- Amazon S3 Cookbook
- Oracle BAM 11gR1 Handbook
- Java應(yīng)用開發(fā)技術(shù)實例教程
- GameMaker Programming By Example
- 機器學(xué)習(xí)與R語言實戰(zhàn)
- HTML5 APP開發(fā)從入門到精通(微課精編版)
- Python從入門到精通
- Learning Hadoop 2
- Java Web從入門到精通(第2版)
- ActionScript 3.0從入門到精通(視頻實戰(zhàn)版)
- C語言程序設(shè)計
- Spring Boot從入門到實戰(zhàn)
- Java EE輕量級解決方案:S2SH