一、数组
数组在内存中是连续 存储 的,所以它的索引速度非常快,而且赋值与修改元素也很简单。
1、一维数组
声明一个数组:
int[] array = new int[5];
初始化一个数组:
int[] array1 = new int[5] { 1, 3, 5, 7, 9 }; //定长
声明并初始化:
int[] array2 = { 1, 3, 5, 7, 9 }; //不定长
2、多维数组
int[,] numbe rs = new int[3, 2] { {1, 2}, {3, 4}, {5, 6} };
但是数组存在一些不足的地方。在数组的两个数据间插入数据是很麻烦的,而且在声明数组的时候必须指定数组的长度,数组的长度过长,会造成内存浪费,过短会造成数据溢出的错误。如果在声明数组时我们不清楚数组的长度,就会变得很麻烦。
针对数组的这些缺点,.net中最先提供了ArrayList对象来克服这些缺点。
二、ArrayList
ArrayList是命名空间Sys te m.Collec ti ons下的一部分,在使用该类时必须进行引用,同时继承了IList 接口 ,提供了数据存储和检索。ArrayList对象的大小是按照其中存储的数据来动态扩充与收缩的。所以,在声明ArrayList对象时并不需要指定它的长度。
ArrayList list1 = new ArrayList(); //新增数据 list1.Add(“cde”); list1.Add(5678); //修改数据 list[2] = 34; //移除数据 list.RemoveAt(0); //插入数据 list.Insert(0, “qwe”);
我们从上面的例子看,在List中,我们不仅插入了 字符 串cde,而且插入了数字5678。这样在ArrayList中插入不同类型的数据是允许的。因为ArrayList会把所有插入其中的数据当作为object类型来处理,在我们使用ArrayList处理数据时,很可能会报类型不匹配的错误,也就是ArrayList不是类型安全的。在存储或检索值类型时通常发生装箱和取消装箱操作,带来很大的性能耗损。
补充:数组扩容 这是对ArrayList效率影响比较大的一个因素。 每当执行Add、AddRange、Insert、InsertRange等添加元素的方法,都会检查内部数组的容量是否不够了,如果是,它就会以当前容量的两倍来重新构建一个数组,将旧元素Copy到新数组中,然后丢弃旧数组,在这个临界点的扩容操作,应该来说是比较影响效率的。 例1:比如,一个可能有200个元素的数据动态添加到一个以默认16个元素大小创建的ArrayList中,将会经过: 16*2*2*2*2 = 256 四次的扩容才会满足最终的要求,那么如果一开始就以: ArrayList List = new ArrayList( 210 ); 的方式创建ArrayList,不仅会减少4次数组创建和Copy的操作,还会减少内存使用。 例2:预计有30个元素而创建了一个ArrayList: ArrayList List = new ArrayList(30); 在过程中,加入了31个元素,那么数组会扩充到60个元素的大小,而这时候不会有新的元素再增加进来,而且有没有调用TrimSize方法,那么就有1次扩容的操作,并且浪费了29个元素大小的空间。如果这时候,用: ArrayList List = new ArrayList(40); 那么一切都解决了。 所以说,正确的预估可能的元素,并且在适当的时候调用TrimSize方法是提高ArrayList使用效率的重要途径。
三、List 因为ArrayList存在不安全类型与装箱拆箱的缺点,所以出现了泛型的概念。List类是ArrayList类的泛型等效类,它的大部分用法都与ArrayList相似,因为List类也继承了IList接口。最关键的区别在于,在声明List集合时,我们同时需要为其声明List集合内数据的对象类型。