數(shù)組用于保存固定數(shù)量的數(shù)據(jù)攻晒,定長,占用內存少班挖,遍歷速度快鲁捏;
集合保存的數(shù)據(jù)數(shù)量,可以在程序的執(zhí)行過程中萧芙,不斷發(fā)生變化给梅,不定長,占用內存多双揪,遍歷速度慢动羽;
在功能上,數(shù)組能實現(xiàn)的所有功能渔期,集合都能實現(xiàn)运吓;反之渴邦,集合能實現(xiàn)的某些功能,數(shù)組難以實現(xiàn)拘哨。
下面以List集合為例谋梭,具體說明集合與數(shù)組的區(qū)別:
定義的格式
集合:List <數(shù)據(jù)類型> 變量名; List<OneClass> classList;
數(shù)組:數(shù)據(jù)類型 [ ] 變量名; int[] arr;
賦值
集合:變量名 = new List <數(shù)據(jù)類型> ( ); 集合是不定長的,所以賦值時無須制定長度倦青,賦值后長度可以變化瓮床。
數(shù)組:變量名 = new 數(shù)據(jù)類型 [長度]; 由于數(shù)據(jù)的定長性,所以賦值時必須指定長度姨夹,賦值后長度固定不變
初始化器
集合: 變量名 = new List <數(shù)據(jù)類型> { 元素1纤垂,元素2,... ...磷账,元素n };
數(shù)組: 變量名 = new 數(shù)據(jù)類型 [ 長度 ] {元素1峭沦,元素2,... ...逃糟,元素n};
數(shù)據(jù)類型 [ ] 變量名 = {元素1吼鱼,元素2,... ...绰咽,元素n}; 數(shù)組初始化器的簡化寫法菇肃,不適用于集合。
由于集合不定長性取募,集合可以添加琐谤、插入、刪除玩敏、修改元素斗忌,還可獲取元素數(shù)量,以List集合為例分別說明:
- 添加元素
變量名.Add (要添加的數(shù)據(jù))旺聚; 其中添加的數(shù)據(jù)類型必須與集合定義時規(guī)定的元素類型一致
- 插入元素
變量名.Insert(索引织阳,要插入的數(shù)據(jù)); 向集合中制定的索引位置砰粹,插入一個新的元素
- 刪除元素
變量名.RemoveAt(索引)唧躲; 刪除制定索引位置的元素
變量名.Remove(數(shù)據(jù)); 刪除集合中與填寫的數(shù)據(jù)相同的第一個匹配項
ps:添加碱璃、插入弄痹、刪除元素后,集合的索引將自動重新編排
- 修改元素
變量名. [索引] = 值厘贼; 讀取和修改元素與數(shù)組的操作方法完全一致
- 獲取元素數(shù)量
集合: 變量名.Count
數(shù)組:變量名.Length
數(shù)組:數(shù)組是相同數(shù)據(jù)類型的元素按一定順序排列的集合界酒。
優(yōu)點:數(shù)組在內存中是連續(xù)存儲的,所以可以快速而且容易的從頭到尾遍歷元素嘴秸。對于數(shù)組賦值以及修改數(shù)組中的值也是非常簡單的。
缺點:但是數(shù)組有一個很大的不足就是,在聲明數(shù)組的時候必須聲明指定長度的數(shù)組岳掐,所以數(shù)組適合于實現(xiàn)已經(jīng)確定的數(shù)據(jù)數(shù)量的情況凭疮。否則就可能會造成聲明的長度過長導致內存空間浪費,過段則造成數(shù)據(jù)的溢出串述。而且再兩個數(shù)據(jù)中間插入數(shù)據(jù)也是非常麻煩的执解,需要將插入位置后面的數(shù)組全都移動位置。
為了克服這些缺點纲酗,就引出了集合的概念衰腌。.NET Framework中提供了用于數(shù)據(jù)存儲和檢索的專用類,這些類統(tǒng)稱為集合觅赊。
ArrayList
ArrayList是命名空間System.Collections下的一部分右蕊,在使用該類時必須進行引用,同時繼承了IList接口吮螺,提供了數(shù)據(jù)存儲和檢索饶囚。ArrayList對象的大小是按照其中存儲的數(shù)據(jù)來動態(tài)擴充與收縮的。所以鸠补,在聲明ArrayList對象時并不需要指定它的長度萝风。
它是使用大小可按需動態(tài)增加的數(shù)組實現(xiàn)IList接口(定義了很多集合使用的方法)。所以ArrayList的初始容量為0紫岩,隨著元素添加進來规惰,容量就會根據(jù)需要重新分配。
優(yōu)點:ArrayList可以根據(jù)使用大小按需動態(tài)增加泉蝌,不用事先設置其大小的控制歇万,還可以隨意地添加、插入或移除某一范圍元素梨与,比數(shù)組要方便堕花。
缺點:但是ArrayList不是類型安全的,它把插入值類型的數(shù)據(jù)都當做object類型粥鞋,當調用數(shù)據(jù)的時候就可能會出現(xiàn)類型不匹配的錯誤缘挽。所以ArrayList存放值類型的數(shù)據(jù)時就需要進行裝箱拆箱的操作,但是這項操作需要進行大量的計算也就帶來了很大的性能損耗呻粹。
using System.Collections;//增加命名空間
public partial class Form1:Form
{
IList arrayAnimal;
//動物報名按鈕事件
private void button3_Click(object sender,EventArgs e)
arrayAnimal=new ArrayList();
arrayAnimal.Add(new Cat("喵喵"));
arrayAnimal.Add(new Cat("咪咪"));
arrayAnimal.RemoveAt(1);//喵喵退出
}
裝箱:把值類型打包到object引用類型的一個實例中壕曼。
//整型變量i被裝箱并復制給對象o
int i=123;
object o=(object) i;
拆箱:從對象中提取值類型等浊。
//對象O拆箱并將其賦值給整型變量i
o=123;
i=(int)o;
由于ArrayList存在的問題腮郊,C#在2.0版之后推出了新的技術來解決這些問題------泛型。
ArrayList list1 = new ArrayList();
//新增數(shù)據(jù)
list1.Add("cde");
list1.Add(5678);
//修改數(shù)據(jù)
list[2] = 34;
//移除數(shù)據(jù)
list.RemoveAt(0);
//插入數(shù)據(jù)
list.Insert(0, "qwe");
從上面例子看筹燕,ArrayList好像是解決了數(shù)組中所有的缺點轧飞,為什么又會有List衅鹿?
從上面的例子看,在List中过咬,我們不僅插入了字符串cde大渤,而且插入了數(shù)字5678。這樣在ArrayList中插入不同類型的數(shù)據(jù)是允許的掸绞。因為ArrayList會把所有插入其中的數(shù)據(jù)當作為object類型來處理泵三,在我們使用ArrayList處理數(shù)據(jù)時,很可能會報類型不匹配的錯誤衔掸,也就是ArrayList不是類型安全的烫幕。在存儲或檢索值類型時通常發(fā)生裝箱和取消裝箱操作,帶來很大的性能耗損敞映。
裝箱與拆箱的概念:
簡單的說:
裝箱: 就是將值類型的數(shù)據(jù)打包到引用類型的實例中. 比如將string類型的值abc賦給object對象obj
拆箱:就是從引用數(shù)據(jù)中提取值類型. 比如將object對象obj的值賦給string類型的變量i
泛型List
泛型是具有占位符(類型參數(shù))的類较曼、結構、接口和方法驱显,這些占位符是類诗芜、結構、接口和方法所存儲或使用的一個或多個類型的占位符埃疫。泛型集合類可以將類型參數(shù)用作他所存儲的對象的占位符伏恐;類型參數(shù)作為其字段的類型和其方法的參數(shù)類型出現(xiàn)。
說白了就是在IList和List后面添加了<T>栓霜,T就是需要指定的集合的數(shù)據(jù)或對象類型翠桦。
List類是ArrayList類的泛型等效類,它的大部分用法都與ArrayList相似胳蛮,因為List類也繼承了IList接口销凑。最關鍵的區(qū)別在于,在聲明List集合時仅炊,我們同時需要為其聲明List集合內數(shù)據(jù)的對象類型斗幼。
List<string> list = new List<string>();
//新增數(shù)據(jù)
list.Add(“abc”);
//修改數(shù)據(jù)
list[0] = “def”;
//移除數(shù)據(jù)
list.RemoveAt(0);
HashTable
是一種數(shù)據(jù)結構,通過鍵(key)和值(value)來組織的抚垄。訪問HashTable元素是可以通過鍵名來獲取具體值蜕窿,但是由于值類型也被轉化為object類型,所以得到一個值類型時也需要轉化呆馁,進行拆箱裝箱操作桐经。
泛型集合(Dictionary<K,V>)
具有泛型的全部特性,存儲數(shù)據(jù)的方式和HashTable類似浙滤,通過鍵和值保存元素的阴挣。它在編譯時需要檢查類型的約束,獲取元素是無需類型轉換纺腊,所以在讀取值類型數(shù)據(jù)的時候就不需要進行裝箱畔咧、拆箱的操作茎芭。
總結:
數(shù)組的容量是固定的,您只能一次獲取或設置一個元素的值盒卸,而ArrayList或List<T>的容量可根據(jù)需要自動擴充骗爆、修改次氨、刪除或插入數(shù)據(jù)蔽介。
數(shù)組可以具有多個維度,而 ArrayList或List<T>始終只具有一個維度煮寡。但是虹蓄,您可以輕松創(chuàng)建數(shù)組列表或列表的列表。特定類型(Object 除外)的數(shù)組 的性能優(yōu)于ArrayList的性能幸撕。這是因為ArrayList的元素屬于Object類型薇组;所以在存儲或檢索值類型時通常發(fā)生裝箱和取消裝箱操作。不過坐儿,在不需要重新分配時(即最初的容量十分接近列表的最大容量)律胀,List<T> 的性能與同類型的數(shù)組十分相近。
在決定使用List<T> 還是使用ArrayList(兩者具有類似的功能時貌矿,記住List<T>類在大多數(shù)情況下執(zhí)行得更好并且是類型安全的炭菌。如果對List<T> 類的類型T使用引用類型,則兩個類的行為是完全相同的逛漫。但是黑低,如果對類型T使用值類型,則需要考慮實現(xiàn)和裝箱問題酌毡。