C 陣列 ArrayList List三者的區別

2021-09-07 23:29:02 字數 4427 閱讀 7262

在c#中,arraylist,list都能夠儲存一組物件,那麼這三者到底有什麼樣的區別呢。

陣列在c#中是最早出現的。它在記憶體中是連續的儲存的,所以索引速度很快,而且賦值與修改元素也很簡單。可以利用偏移位址訪問元素,時間複雜度為o(1);可以用折半查詢法查詢元素,效率高。

string[

] s=new string[3]

;//賦值s[0

]="a";s[1

]="b";s[2

]="c";

//重新賦值s[1

]="b1"

;

同時,陣列也有很多缺點。陣列分配在一塊連續的資料空間上,因此分配空間時必須確定大小。空間的連續,也導致了儲存效率低,插入和刪除元素效率比較低,而且麻煩。如果,要增添乙個元素,需要移動大量元素,在記憶體中空出乙個元素的空間,然後將要增加的元素放在其中。同樣,你想刪除乙個元素,需要移動大量元素去填補被移動的元素。

還有我們在宣告陣列的時候,必須同時指明陣列的長度,陣列的長度過長,會造成記憶體浪費,陣列和長度過短,會造成資料溢位的錯誤。這樣如果在宣告陣列時我們並不清楚陣列的長度,就變的很棘手了。

針對於陣列的這些缺點,c#中最先提供了arraylist物件來克服這些缺點。

arraylist是.net framework提供的用於資料儲存和檢索的專用類,它是命名空間system.collections下的一部分。它的大小是按照其中儲存的資料來動態擴充與收縮的。所以,我們在宣告arraylist物件時並不需要指定它的長度。

arraylist繼承了ilist介面,所以它可以很方便的進行資料的新增,插入和移除。例如:

arraylist list = new arraylist()

;//新增資料

list.

add(

"abc");

list.

add(

123)

;//修改資料

list[1]

=345

;//移除資料

list.

removeat(0

);//插入資料

list.

insert(0

,"hello world");

//獲取元素值

object value = al[index]

;//al 為 arraylist 物件,一般需要再對 value 進行型別轉換,比如:int n = (int)value;

//設定元素值

al[index]

= value;

//al 為 arraylist 物件,index 必須小於 count

//追加元素

int arraylist.

add(object value)

//返回新增的元素的索引

//插入元素

void arraylist.

insert

(int index, object value)

//刪除元素

//刪除元素後,後面的元素會前移,但 capacity 不會變化。

void arraylist.

remove

(object obj)

//從前(索引 0)往後查詢,刪除找到的第乙個和 obj 相同的元素

void arraylist.

removeat

(int index)

//刪除索引 index 對應的元素

void arraylist.

removerange

(int index,

int count)

//從索引 index 開始,刪除 count 個元素

//查詢元素

int arraylist.

indexof

(object value)

//從前(索引 0)往後查詢,返回找到的第乙個和 obj 相同的元素的索引

int arraylist.

indexof

(object value,

int startindex)

int arraylist.

indexof

(object value,

int startindex,

int count)

int arraylist.

lastindexof

(object value)

//從後往前(索引 0)查詢,返回找到的第乙個和 obj 相同的元素的索引

int arraylist.

lastindexof

(object value,

int startindex)

int arraylist.

lastindexof

(object value,

int startindex,

int count)

從上面示例看,arraylist好像是解決了陣列中所有的缺點,那麼它應該就是完美的了,為什麼在c#2.0後又會出現list呢?

還是從上面的示例看,在list中,我們不僅插入了字串"abc",而且又插入了數字123。這樣在arraylist中插入不同型別的資料是允許的。因為arraylist會把所有插入其中的資料都當作為object型別來處理。這樣,在我們使用arraylist中的資料來處理問題的時候,很可能會報型別不匹配的錯誤,也就是說arraylist不是型別安全的。既使我們保證在插入資料的時候都很小心,都有插入了同一型別的資料,但在使用的時候,我們也需要將它們轉化為對應的原型別來處理。這就存在了裝箱與拆箱的操作,會帶來很大的效能損耗。

穿插一下裝箱與拆箱的概念:

簡單的來講:

裝箱:就是將值型別的資料打包到引用型別的例項中

比如將int型別的值123賦給object物件o

int i=

123;

object o=

(object)i;

拆箱:就是從引用資料中提取值型別

比如將object物件o的值賦給int型別的變數i

object o=

123;

int i=

(int

)o;

裝箱與拆箱的過程是很損耗效能的

正是因為arraylist存在不安全型別與裝箱拆箱的缺點,所以在c#2.0後出現了泛型的概念。而list類是arraylist類的泛型等效類。它的大部分用法都與arraylist相似,因為list類也繼承了ilist介面。最關鍵的區別在於,在宣告list集合時,我們同時需要為其宣告list集合內資料的物件型別。

list<

int> list = new list<

int>()

;//新增資料

list.

add(

123)

;//修改資料

list[0]

=345

;//移除資料

list.

removeat(0

);

上例中,如果我們往list集合中插入string字元"hello world",ide就會報錯,且不能通過編譯。這樣就避免了前面講的型別安全問題與裝箱拆箱的效能問題了。

console.

writeline

("list test:");

//宣告乙個整型的list

list<

int> lstest = new list<

int>()

; lstest.

add(7)

; lstest.

add(5)

; lstest.

add(1)

; lstest.

add(3)

; string strtest="";

//list的排序

lstest.

sort()

;//list的遍歷

foreach

(int i in lstest)

strtest+

=i.tostring()

+" "

;//格式化後輸出

console.

write

(string.

format

("out: ncount:n"

,strtest,lstest.count));

//讀取下乙個按鍵,以便讓螢幕顯示資料

console.

readkey()

;

出結果如下:

程式**

list test:

out:13

57 count:

4

文字摘自,如有需要請看原文:

c 陣列 和 陣列指標

今天 乙個朋友 面試,面試題如下 int tmain int argc,tchar argv int ptr int a 1 printf d t d a 1 ptr 1 return 0 我覺得 指標 只要 掌握 兩方面資訊 就 沒什麼 可難的了.一是 指標變數 裡 存放的 位址 二是 指標變數 ...

C語言 陣列(字元陣列)

軟體中,文字處理比數字處理更重要,而處理文字時需要用到字串,所以掌握字串的知識很重要。字串一定有 0 結尾,只有以 0 結尾的字元陣列才能稱為字串。0 是字串的標誌,也是字串結束的標誌。一 字串的定義 char arr 10 char brr 5 不是字串,沒有 0 char crr 5 最後乙個元...

c 陣列,2維陣列

也就是區域性變數的一維陣列,在編譯的時候其維度必須是已知的,因此維度必須是乙個常量表示式。int a ok int a 4 int b a wrong!也就是用new 搞出來的,維度可以是乙個變數 int a 4 int b new int a ok!int a 這是個5行4列的陣列,不過實際c 沒...