在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 沒...