1、什么是ArrayList
ArrayList是传说中的动态数组,在MSDN中被称为Array的复杂版本。 这提供了以下好处:
的要素动态增加和减少
实现了ICollection和IList接口
灵活设置数组的大小
2、ArrayList的使用方法
最简单的例子:
ArrayList List=new ArrayList (;
for(intI=0; i 10; 在I//数组中添加10个Int元素
list.add(I;
//程序进行一些处理
list.removeat(5;//删除第6个要素
for(intI=0; i 3; I )//再增加三种元素
list.add(I20;
int32[]values=(int32[] ) list.toarray ) typeof(int32 ); 返回ArrayList中包含的数组
这是一个简单的示例,并不包含ArrayList的所有方法,但它反映了ArrayList最常见的用法
3、ArrayList重要方法和属性
1 )构造函数
ArrayList有三个构造函数。
公共阵列(;
的默认构造函数以默认(16 )的大小初始化内部数组
公共阵列(I collection;
使用ICollection对象构建,并将集合的元素添加到ArrayList中
公共阵列列表(int;
以指定的大小初始化内部数组
2 ) is同步属性和ArrayList.Synchronized方法
IsSynchronized属性指示当前ArrayList实例是否支持线程同步,ArrayList.Synchronized静态方法返回ArrayList线程同步的封装。
如果使用线程未同步的实例,则在多线程访问时,必须自己手动调用lock以保持线程同步。 示例:
ArrayList list=new ArrayList (;
//.
对于lock(list.SyncRoot )数组包装器,SyncRoot属性实际上是自己,但为了满足ICollection的SyncRoot定义,在此使用SyncRoot
{
list.add(「addaitem”);
}
使用ArrayList.Synchronized方法返回的实例不需要考虑线程同步问题。 此实例本身是线程安全的。 实际上,ArrayList内部实现了一个确保线程同步的内部类,ArrayList.Synchronized返回的是该类的实例,其中的每个属性都使用lock
3 ) Count和Capacity属性
Count属性是当前ArrayList中包含的元素数,为只读。
Capacity属性是当前ArrayList中可以包含的最大数量,可以手动设置,但如果设置为小于Count值,则会引发异常。
4 )添加、添加范围、移除、移除at、移除范围、插入、插入范围
这些方法比较相似
Add方法将元素添加到当前列表的末尾
使用AddRange方法将一组元素添加到当前列表的末尾
Remove方法删除元素,并通过元素本身的引用将其删除
RemoveAt方法删除元素,并按索引值删除
RemoveRange用于删除一组元素,通过指定要开始的索引和要删除的数量来删除
Insert用于在指定位置添加元素,列表后面的元素按顺序向后移动
插入范围用于从指定位置添加一组元素,列表后面的元素按顺序向后移动
此外,还有几种类似的方法:
Clear方法用于清除所有现有元素
Contains方法用于查找不在列表中的对象
其他的我一点也不麻烦。 请看MSDN。 上面的话请再仔细看看
5 )三重化方法
此方法用于将ArrayList固定为实际元素的大小,并且可以在确定未添加动态数组元素时调用以释放空闲内存。
6 )待阵列方法
此方法将ArrayList的元素Copy存储在新数组中。
4、数组转换
示例1 :
ArrayList List=new ArrayList (;
list.add(1;
列表
.Add(2);List.Add(3);
Int32[] values = (Int32[])List.ToArray(typeof(Int32));
例2:
ArrayList List = new ArrayList();
List.Add(1);
List.Add(2);
List.Add(3);
Int32[] values = new Int32[List.Count];
List.CopyTo(values);
上面介绍了两种从ArrayList转换到数组的方法
例3:
ArrayList List = new ArrayList();
List.Add( “string” );
List.Add( 1 );
//往数组中添加不同类型的元素
object[] values = List.ToArray(typeof(object)); //正确
string[] values = (string[])List.ToArray(typeof(string)); //错误
和数组不一样,因为可以转换为Object数组,所以往ArrayList里面添加不同类型的元素是不会出错的,但是当调用ArrayList方法的时候,要么传递所有元素都可以正确转型的类型或者Object类型,否则将会抛出无法转型的异常。
5、ArrayList最佳使用建议
这一节我们来讨论ArrayList与数组的差别,以及ArrayList的效率问题
1)ArrayList是Array的复杂版本
ArrayList内部封装了一个Object类型的数组,从一般的意义来说,它和数组没有本质的差别,甚
定到实际元素的大小,当动态数组元素确定不在添加的时候,可以调用这个方法来释放空余的内存。
6)ToArray方法
这个方法把ArrayList的元素Copy到一个新的数组中。
4、ArrayList与数组转换
例1:
ArrayList List = new ArrayList();
List.Add(1);
List.Add(2);
List.Add(3);
Int32[] values = (Int32[])List.ToArray(typeof(Int32));
例2:
ArrayList List = new ArrayList();
List.Add(1);
List.Add(2);
List.Add(3);
Int32[] values = new Int32[List.Count];
List.CopyTo(values);
上面介绍了两种从ArrayList转换到数组的方法
例3:
ArrayList List = new ArrayList();
List.Add( “string” );
List.Add( 1 );
//往数组中添加不同类型的元素
object[] values = List.ToArray(typeof(object)); //正确
string[] values = (string[])List.ToArray(typeof(string)); //错误
和数组不一样,因为可以转换为Object数组,所以往ArrayList里面添加不同类型的元素是不会出错的,但是当调用ArrayList方法的时候,要么传递所有元素都可以正确转型的类型或者Object类型,否则将会抛出无法转型的异常。
5、ArrayList最佳使用建议
这一节我们来讨论ArrayList与数组的差别,以及ArrayList的效率问题
1)ArrayList是Array的复杂版本
ArrayList内部封装了一个Object类型的数组,从一般的意义来说,它和数组没有本质的差别,甚至于ArrayList的许多方法,如Index、IndexOf、Contains、Sort等都是在内部数组的基础上直接调用Array的对应方法。
2)内部的Object类型的影响
对于一般的引用类型来说,这部分的影响不是很大,但是对于值类型来说,往ArrayList里面添加和修改元素,都会引起装箱和拆箱的操作,频繁的操作可能会影响一部分效率。
但是恰恰对于大多数人,多数的应用都是使用值类型的数组。
消除这个影响是没有办法的,除非你不用它,否则就要承担一部分的效率损失,不过这部分的损失不会很大。
3)数组扩容
这是对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使用效率的重要途径。
4)频繁的调用IndexOf、Contains等方法(Sort、BinarySearch等方
法经过优化,不在此列)引起的效率损失
首先,我们要明确一点,ArrayList是动态数组,它不包括通过Key或者Value快速访问的算法,所以实际上调用IndexOf、Contains等方法是执行的简单的循环来查找元素,所以频繁的调用此类方法并不比你自己写循环并且稍作优化来的快,如果有这方面的要求,建议使用Hashtable或SortedList等键值对的集合。
ArrayList al=new ArrayList();
al.Add("How");
al.Add("are");
al.Add("you!");
al.Add(100);
al.Add(200);
al.Add(300);
al.Add(1.2);
al.Add(22.8);