定义
用一组连续的内存空间存储一组具有相同类型的数据的线性表数据结构。
优势
支持通过下标快速的随机访问数据,时间复杂度为O(1)。
劣势
通常情况下,插入和删除效率低下,每次操作后,需要进行后续元素的移位,时间复杂度为O(n)。
上面也说了通常情况下,那也就代表有时候我们也可以稍微优化一下,使其效率更高。
比如在插入的时候,直接将要插入位置k的元素挪到数组最后面,然后将新的元素放入位置k上,在部分情况下,就能满足我们的需求。
再说删除操作,我们可以在删除的时候,不急着将后面元素前移,而是先标记一下,等空间不够时,统一进行位移,听起来有点类似JVM的标记清除垃圾回收算法。
介绍完数组,再说一下数组类型的容器类,以Java中的ArrayList为例。
ArrayList主要为我们做了什么事情呢?
1. 封装操作细节:插入、删除时搬移其他元素的操作;
2. 动态扩容;
3. 运行时,当碰到并发问题时,通过抛出CME(ConcurrentModificationException)提醒使用者。
浅析ArrayList源码
插入
1. 在最后插入
public
2. 在指定位置插入
public
删除
- 删除指定元素
public
2. 删除指定位置元素
public
扩容
尝试将数组大小扩容到原来的1.5倍
private
并发检测相关
通过添加删除时修改的modCount进行检测,如果在遍历容器元素的过程中,modCount发生了修改,就会抛出CME。
final
如果有迭代删除元素的需求,通常使用迭代器Iterator,其中的remove操作,因为代码
expectedModCount
的存在,支持迭代过程中删除元素(如果是迭代过程中,其他线程对该容器进行了add或者remove操作,仍然会抛出CME)。