程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> 關於C# >> (教學思路 C#集合一)集合的概述、動態數組ArrayList

(教學思路 C#集合一)集合的概述、動態數組ArrayList

編輯:關於C#

這一節我們來學習集合,什麼是集合呢? 集合就如同數組,用來存儲和管理一組特定類型的數據對象,除了基本的數據處理功能,集合直 接提供了各種數據結構及算法的實現,如隊列、鏈表、排序等,可以讓你輕易地完成復雜的數據操作。在使用數組和集合時要先加入 system.collections命名空間,它提供了支持各種類型集合的接口及類。集合本身上也是一種類型,基本上可以將其作為用來存儲一組數據對 象的容器,由於c#面向對象的特性,管理數據對象的集合同樣被實現成為對象,而存儲在集合中的數據對象則被稱為集合元素。這裡提到了接 口這個概念,它也是面向對象編程進化的重要標准,我們在這裡不做過多的講解,先注重學習集合中的對象及其使用就可以了,下面我們來學 習第一種集合:

動態數組ArrayList.ArrayList類提供了繼承了IList接口。什麼是繼承呢?這也是面向對象語言的重要特點之一,現在你們先把它理解為, 如果一個對象繼承了類或接口,那麼它也具有了這個類和接口中的方法、屬性,可以用這些繼承的方法和屬性來做相應的操作,比如:數組增 加元素沒有Add()方法,但是動態數組ArrayList繼承了一個增加元素有Add()方法的接口,那麼當它要增加元素的時候,不僅可以用索引, 也可以用繼承下來的Add()方法了。隨著學習的深入,我會給大家再具體講解繼承的概念和使用繼承的好處。那麼下面讓我們來看看動態數組 所繼承的這個接口IList它有什麼特性呢?

Ilist接口:定義了利用索引訪問集合對象的方法,還繼承了ICollection和IEnumerable接口,除實現了接口原有的方法成員外,其本身也 定義多個專門的方法成員,例如新增、移除、在指定位置插入元素或是返回特定元素在集合中所在的位置索引,這些方法主要為集合對象提供 類似數組的元素訪問功能。

ILsit接口成員:add、insert、RemoveAt、Remove、contains、Clear、indexof方法,它最大的特色在於提供類 似數組索引的訪問機制。

ArrayList對象是較為復雜的數組。我們可以將它看為擴充了功能的數組,但ArrayList並不等同於數組,與數組相比,它以下功能和區別是 :

1. 數組的容量是固定的,但ArrayList的容量可以根據需要自動擴充。當我們修改了ArrayList的容量時,則可以自動進行內存重新分配和 元素復制,比如往1號索引位插入n個元素,插入後,元素的索引依次向後n個位置排列,它是動態版本的數組類型。

2.ArrayList提供添加、插入或移除某一范圍元素的方法。但是在數組中,只能一次獲取或設置一個元素的值,如利用索引賦值。

3.ArrayList只有一維,而數組可以是多維。

4.ArrayList可以存放任何數據類型的數據,而數組只能存儲同種數據類型的數據。

這種可以存放任何數據類型的機制,我們稱為裝箱,本節課的後半部分我會講解到,現在大家只需要記住,無論是什麼數據類型,只要添加 到動態數組中,都將轉變為Object數據類型,所以在遍歷Arraylist時,要定義一個Object類型的變量,用來接收遍歷它的每個項的值。

如何聲明一個動態數組呢?

ArrayList AL=new ArrayList( Capacity );//初始容量capacity也是可以不寫的

原因就是即使不在初識化確定容量,容量不夠的時候,會自動的按倍數作擴充。

接下來我們來看一下動態數組的常用屬性

Capacity 獲取或設置ArrayList可包含的元素數。

Count 獲取ArrayList中實際包含的元素數。

IsReadOnly 獲取一個值,該值表示ArrayList是否為只讀。

Item 獲取或設置指定索引處的元素。

動態數組的常用方法

增加元素-AL.Add(value);利用Add方法增加集合元素值

修改元素-AL[Index]=value;利用索引的方式修改元素的值

插入元素-AL.Insert(Index,value);將元素的值value,插入到第Index位置 。

刪除元素-AL.Clear(); 全部刪除集合中的元素

AL.Remove(value);按照集合元素值刪除元素

AL.RemoveAt(Index);按照集合的元素索引刪除元素

縮減容量-AL.TrimToSize();將集合的容量減少到實際元素個數的大小

在執行刪除操作後,要養成良好的縮減容量的習慣,節省內存空間,提高性能。

查找元素-除了按數組的索引查找外,還可以用 AL.Contains(value);按照元素值查找集合,如果包含便返回True,不包含時返回False。

得到類型--AL[index].GetType() 可以得到在index索引位的元素的數據類型

元素排序-- AL.Sort();

元素反轉-- AL.Reverse();

下面的例子我會給你們分部的演示出以上方法及屬性,運行結果我會用圖片的形式顯示出來,幫助你們理解動態數組是使用。

添加元素和得到數據類型

1 ArrayList AL = new ArrayList();
2 Console.WriteLine("容量: " + AL.Capacity);
3 Console.WriteLine("給動態數組添加元素:");
4 AL.Add("Hello");
5 Console.WriteLine("容量: " + AL.Capacity);
6 AL.Add(" World");
7 foreach (Object obj in AL)
8 {
9 Console.Write(obj);
10 }
11 Console.WriteLine();
12 Console.WriteLine("個數:" + AL.Count);
13 Console.WriteLine ("容量: " + AL.Capacity);
14 Console.WriteLine("第1個元素的數據類型為:" + AL[0].GetType ());

插入

1 AL.Insert(1, " c#");
2 Console.Write("在索引值為1的地方插入 ");
3 foreach (Object obj in AL)
4 { Console.Write(obj); }
5 Console.WriteLine();
6 Console.WriteLine("個數:" + AL.Count);
7 Console.WriteLine("容量: " + AL.Capacity);

結果容量: 0

給動態數組添加元素:

容量: 4

Hello World

個數:2

容量: 4

第1個元素的數據類型為:System.String

在 索引值為1的地方插入 Hello c# World

個數:3

容量: 4

請按任意鍵繼續. . .

擴充容量

1 AL.Add("。");
2 Console.WriteLine("容量。: " + AL.Capacity);
3 AL.Add("---");
4 Console.WriteLine("容量---: " + AL.Capacity);
5
6 foreach (Object obj in AL)
7 { Console.Write(obj); }

結果容量: 0

給動態數組添加元素:

容量: 4

Hello World

個數:2

容量: 4

第1個元素的數據類型為:System.String

在 索引值為1的地方插入 Hello c# World

個數:3

容量: 4

容量。: 4

容量---: 8

Hello c# World。---

請按任意鍵繼續. . .

根據索引找到元素

1 Console.WriteLine("\n3號索引的:" + AL[3]);
2 Console.WriteLine("集合中是否包含?: " + AL.Contains("?"));
3 Console.WriteLine("經過之前操作後的集合元素:");
4 foreach (Object obj in AL)
5 { Console.Write(obj); }
6
7 Console.WriteLine("\n個 數:" + AL.Count);
8 Console.WriteLine("容量: " + AL.Capacity);

結果

容量: 0

給動態數組添加元素:

容量: 4

Hello World

個數:2

容量: 4

第1個元素的數據類型為:System.String

在索引 值為1的地方插入 Hello c# World

個數:3

容量: 4

容量。: 4

容量---: 8

Hello c# World。---

3號索引的:。

數組中是否 包含?:False

經過之前操作後的數組元素:

Hello c# World。---

個數:5

容量: 8

請按任意鍵繼續. . .

按值刪

1 AL.Remove("。");
2 AL.Remove("?");
3
4 Console.WriteLine("沒有?個數只減少1個容量不變");
5 foreach (Object obj in AL)
6 { Console.Write(obj); }
7 Console.WriteLine();
8 Console.WriteLine("個數:" + AL.Count);
9 Console.WriteLine("容量: " + AL.Capacity);

結果

容量: 0

給動態數組添加元素:

容量: 4

Hello World

個數:2

容量: 4

第1個元素的數據類型為:System.String

在索引值為1的地方插入 Hello c# World

個數:3

容量: 4

容量。: 4

容量---: 8

Hello c# World。---

3號索引的:。

數組 中是否包含?:False

經過之前操作後的數組元素:

Hello c# World。---

個數:5

容量: 8

沒有?個數只減少1個容量不變

Hello c# World---

個數:4

容量: 8

請按任意鍵繼續. . .

按照索引刪 1 AL.RemoveAt(3);
2 Console.WriteLine("移除3號索引位的元素:");
3 foreach (Object obj in AL)
4 { Console.Write(obj); }
5 Console.WriteLine();
6 Console.WriteLine("個數:" + AL.Count);
7 Console.WriteLine("容量: " + AL.Capacity);
8
9

結果

容量: 0

給動態數組添加元素:

容量: 4

Hello World

個數:2

容量: 4

第1個元素的數據類型為:System.String

在索引 值為1的地方插入 Hello c# World

個數:3

容量: 4

容量。: 4

容量---: 8

Hello c# World。---

3號索引的:。

數組中是否 包含?:False

經過之前操作後的數組元素:

Hello c# World。---

個數:5

容量: 8

沒有?個數只減少1個容量不變

Hello c# World---

個數:4

容量: 8

移除3號索引位的元素:

Hello c# World

個數:3

容量: 8

請按任意鍵繼續. . .

1 AL.TrimToSize(); //縮減容量
2 Console.WriteLine("實際容量: " + AL.Capacity);

結果容量: 0

給動態數組添加元素:

容量: 4

Hello World

個數:2

容量: 4

第1個元素的數據類型為:System.String

在 索引值為1的地方插入 Hello c# World

個數:3

容量: 4

容量。: 4

容量---: 8

Hello c# World。---

3號索引的:。

數組中 是否包含?:False

經過之前操作後的數組元素:

Hello c# World。---

個數:5

容量: 8

沒有?個數只減少1個容量不變

Hello c# World---

個數:4

容量: 8

移除3號索引位的元素:

Hello c# World

個數:3

容量: 8

實際容量: 3

請按任意鍵繼續. . .

1 AL.Clear();
2 Console.WriteLine("清除全部元素後:");
3 Console.WriteLine("個數:" + AL.Count);
4 Console.WriteLine("容量: " + AL.Capacity);

Title容量: 0

給動態數組添加元素:

容量: 4

Hello World

個數:2

容量: 4

第1個元素的數據類型為:System.String

在 索引值為1的地方插入 Hello c# World

個數:3

容量: 4

容量。: 4

容量---: 8

Hello c# World。---

3號索引的:。

數組中 是否包含?:False

經過之前操作後的數組元素:

Hello c# World。---

個數:5

容量: 8

沒有?個數只減少1個容量不變

Hello c# World---

個數:4

容量: 8

移除3號索引位的元素:

Hello c# World

個數:3

容量: 8

實際容量: 3

清除全部元素後:

個數:0

容量: 3

請按任意鍵繼續. . .

通過以上的例子你們應該已經理解集合的方法,我們再來總結一下集合ArrayList相比數組有什麼好處?主要是它可以根據使用大小按需動 態增加,不用受事先設置大小的控制,還有就是可以隨意的添加、插入或移除某一范圍元素,比數組要方便。但是它也有不足,ArrayList 不 管對象是什麼類型都會添加到集合j中,在編譯時都是沒有問題的,但是在遍歷的時候,為防止集合中元素的類型不一致,所以最好使用object 類型來接收遍歷j的元素,如foreach(object i in j)這樣就能減少錯誤,可能同學們會想,用object類型我們記住了,怎麼就成弊端的呢?

這裡我們就要學到另一個知識點,就是裝箱和拆箱。所謂裝箱就是把值類型打包成object引用類型的一個實例中,也就是說在進行裝箱的時 候,必須分配並構造一個全新的對象。而拆箱就是指從對象中提取值類型,將object類型強制轉換為原類型。

比如:

ArrayList j=new ArrayList();

j.Add(123);

j.Add("123");

在添加時,ArrayList是會隱式的將整形的123 進行如下裝箱操作: int i=123; object o=(object)i;也就是說存進j的元素都將變成 object類型

而在使用這個整形的123時,ArrayList又會進行如下的拆箱操作: o=123; i=(int)o; 也就是將o再強制轉換成原來的類型表現出去

想想這將是很大的性能消耗,需要進行大量的計算,至於怎麼記住裝箱拆箱,我們就把這個過程想象成現實生活中,你買了很多中水果(元 素),為了方便搬運,我們把他們都放到一個大盒子(集合對象)裡,但是因為有榴蓮,我們又得把榴蓮(值類型元素)單獨包裝好(裝箱過 程)再放到盒子裡,到了家後,我們要打開盒子取出水果,在拿到榴蓮時,要想見到真正的榴蓮,我們就的把包裝去掉(拆箱),我們馬上就 聞到了榴蓮那獨有的味道了(變回原類型)。哎!這個過程多麻煩呀!分了這麼多步,在C#2.0出來後,就推出了新的技術來解決這個問題,那 就是泛型,以後的章節我會講解這個新特性。

下面我們來講一下ArrayList向數組的互換。

將數組轉換成動態數組

1 //數組轉換成動態數組
2 int[] c = { 1, 2 };
3 //1.利用for循環添加到動態數組中
4 ArrayList d = new ArrayList();
5 for (int i = 0; i < c.Length; i++)
6 {
7 d.Add(c[i]);
8 }
9 //2.使用Adapter方法,將數組打包到動態數組中
10 ArrayList b = ArrayList.Adapter(c);
11 foreach (int i in b)
12 {
13 Console.WriteLine(i);
14 }

動態數組轉換成數組

1 //動態數組轉換成數組
2 ArrayList arl = new ArrayList(4);
3 arl.Add ("W");
4 arl.Add("h");
5 arl.Add("y");
6 //arl.Add(1);
7 //只能將包含同一種數據類型集合轉換成這種類型的數組
8 //如果ar1中a添加了元素整型 1,將無法被轉換為string類型的數組
9 string[] ar = new string[arl.Count];
10
11 //使用typeof (string)限定放入數組ar中的數據都是string類型,
12 //同時再將arl強制轉換string類型數組,賦給數組ar
13 ar = (string[])arl.ToArray(typeof(string));
14 foreach (string a in ar)
15 {
16 Console.Write(a);
17 }

例題:

1 ArrayList al = new ArrayList();//定義一個動態數組
2 Random rd = new Random();//定義一個隨機數對象
3 do
4 {
5 int i = rd.Next(1, 36);//在1-35中產生隨機數
6 if (!al.Contains (i))//如果al不包含隨機數i
7 al.Add(i);//我們就把i添加到動態數組中
8 } while (al.Count < 7);//當動態數組的長度是7的時候,我們停止添加。
9 al.Sort();//排序一下動態數組
10 foreach (object cps in al)
11 Console.WriteLine(cps);//把這7個數用foreach循環打印出來

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved