C# 数组之ArrayList
一、引言
ArrayList类相当于一种高级的动态数组,是Array类的升级版本。
一般的Array,底层是数组实现的,对于数据的查找和修改十分高效。但是有2个大的缺点,其一为增删低效,其二为数组长度时固定的,无法动态增加长度。
与一般的Array相比,ArrayList主要可以动态增加数组的长度。尽管实现了数据增删,但是由于底层还是数组,增删效率还是不高。
二、函数
声明之前需要引用命名空间:using System.Collections
创建:
声明时可指定长度,也可不指定:
ArrayList myList = new ArrayList();
ArrayList myList = new ArrayList(100);
属性:
名称 |
说明 |
获取或设置 ArrayList 可包含的元素数。 |
|
获取 ArrayList 中实际包含的元素数。 |
|
获取一个值,该值指示 ArrayList 是否为只读。 |
方法:
名称 |
描述 |
增加(末尾) |
将对象添加到 ArrayList 的结尾处。 |
插入(任意位置) |
将元素插入 ArrayList 的指定索引处。 |
全部删除 |
从 ArrayList 中移除所有元素。 |
移除(某对象) |
从 ArrayList 中移除特定对象的第一个匹配项。 |
移除(某下标) |
移除 ArrayList 的指定索引处的元素。 |
RemoveRange(index,count) 移除(一段) |
移除ArrayList中,index开始,长度为count的数据 |
克隆 |
创建 ArrayList 的浅表副本。 |
复制 |
从目标数组的开头开始,将整个 ArrayList 复制到兼容的一维 Array。 |
复制一段 |
复制 ArrayList 中一个子集合的元素。 |
Int IndexOf(Object) 查找 |
搜索指定 Object 并返回整个内的第一个匹配项的从零开始索引 ArrayList。 |
Bool Contains(Object) 包含 |
确定某元素是否在 ArrayList 中。 |
逆序 |
将整个 ArrayList 中元素的顺序反转。 |
排序 |
对整个 ArrayList 中的元素进行排序。 |
访问:
ArrayList是数组,因此支持下标直接访问
ArrayList[index] = value;
遍历:
因为ArrayList可以存放任意类型的数据,因此遍历的时候,无法指定一种数据类型,因此:
foreach(Object obj in myList)
{
Console.WritLine(obj);
}
与数组转换:
- 如果ArrayList里面,全是同一种类型,比如int,可以如下转换:
int[] A = ( int[] )Arrlist.ToArray( typeof(int) );
或者
int[] A= new int[Arrlist.Count];
Arrlist.CopyTo(A);
- 如果ArrayList里面,不一定是同一种类型,可以如下转换:
object[] A = Arrlist.ToArray();
三、总结
关于数组扩容:
这是对ArrayList效率影响比较大的一个因素。
每当执行Add、AddRange、Insert、InsertRange等添加元素的方法,都会检查内部数组的容量是否不够了,如果是,它就会以当前容量的两倍来重新构建一个数组,将旧元素Copy到新数组中,然后丢弃旧数组,在这个临界点的扩容操作,应该来说是比较影响效率的。
比如,一个可能有200个元素的数据动态添加到一个以默认16个元素大小创建的ArrayList中,将会经过:
16*2*2*2*2 = 256
四次的扩容才会满足最终的要求,那么如果一开始就以:
ArrayList List = new ArrayList( 210 );
的方式创建ArrayList,不仅会减少4次数组创建和Copy的操作,还会减少内存使用。
所以说,正确的预估可能的元素,并且在适当的时候调用TrimSize方法是提高ArrayList使用效率的重要途径。
(1)数组的容量是固定的,而ArrayList的容量可以根据需要自动扩充
(2)ArrayList可以插入任意类型的数据,而数组必须是同一种类型
(3)ArrayList提供将只读和固定大小包装返回到集合的方法,而数组不提供
(4)ArrayList只是一维形式,而数组可以是多维的
(5)因为ArrayList主打动态数组,但是频繁的扩容会影响效率。因此在初始化的时候,就考虑好大概需要N个数据,初始大小比N稍大就好。
(6)不用频繁的使用indexOf、contains等,数组的查找也是遍历,并没有key、value等映射,效率不高。
写在最后的话:
对于一般的引用类型来说,这部分的影响不是很大,但是对于值类型来说,往ArrayList里面添加和修改元素,都会引起装箱和拆箱的操作,频繁的操作可能会影响一部分效率。但是恰恰对于大多数人,多数的应用都是使用值类型的数组。消除这个影响是没有办法的,除非你不用它,否则就要承担一部分的效率损失,不过这部分的损失不会很大。