在程序编写过程中List的使用频率是相当之高,高过了数组,和Dictionary并起成为dotNet中的两大容器,但也只是会用而已,并不清楚具体的原理,早期我认为List内部是由链表实现的,但实际上并不是那样,本次查看了源码,对常用的基础容易有一定的了解。因ArrayList和List基本相同,所以先对ArrayList剖析,再来对比与List的不同。 数组在声明时就需要确认长度以便申请内存,在内存中是连续并且长度是固定的,索引速度上肯定是最快的,赋值与修改也非常简单,但因长度固定,插入和删除是个比较麻烦的事情,为此诞生了容器类ArrayList。 System.Collections命名空间下ArrayList类

{{EJS0}}

在ArrayList类中有两个字段,_items为该类维护的数组,_size计数(注:数组元素为object类型)

{{EJS1}}

获取ArrayList中元素的数量,返回的也就是维护的_size字段

{{EJS2}}

由此可见,当ArrayList第一次插入数据的时候,会默认分配4个元素长度的空间,如果超出4个则重新建立数组,复制旧数组数据到更大的新数组中,也就是说,第一次插入:会新建一个4元素长度数组,插入第五个元素时:新建一个8长度数组,并把旧数组中元素复制过来,旧数组则等待垃圾回收,以此类推。我们在不断插入元素时,会不断的进行重新分配空间,对元素进行复制的操作,如果我们一开始就知道该容器在业务中需要的大小,则可以在初始化时给一个具体的大小,也就是其中一个构造函数:

{{EJS3}}

另外,ArrayList还提供了Synchronized方法,返回值是一个ArrayList 但实际上在ArrayList类中有一个私有类SyncArrayList,它继承于ArrayList,在ArrayList方法重写增加了锁,以确保线程安全。

{{EJS4}}

  再来看List的代码:

{{EJS5}}

和ArrayList的代码对比,基本完全相同,只是ArrayList维护着object数组,而List是泛型(模板)类,维护着泛型数组,List相比于ArrayList增加了类型安全以及ArrayList因object而引发的装拆箱性能问题。 因现有类型安全更快速的List,所以基本没有人在去用ArrayList了,而对元素的方便操作也让该容器成为最常用的容器之一。