首先是集合的架构图
2者的组成原理上
这其实得从数据结构上理解,数组结构分为线性数据机构和非线性结构:
线性结构上又有着2种不同的存储结构,顺序存储和链式存储,我是直接理解为了数组和链表(其实不能直接理解为链表,因为树这类的也是由链表构成的但是却是属于非线性数据结构)
ArrayList数据结构
Arraylist就是属于属于顺序存储,也就是在计算机里用一组连续的存储单元去依次存储各个元素数据,它节省空间(我的理解时它相对于链表不需要专门记录后继节点),但是相对应的它由于是连续存储,那么对于空间的要求就相对比较高,就是必须得有这么大的空间才能new 出来
至于为什么数组下标是从0开始,计算公式是:a[i]_address = base_address + i*data_type_size
如果从1开始,那么公式变成了:a[i]_address = base_address + (i-1)*data_type_size
就是多了一步的计算操作。也正是因为了这个公式,所以数组可以根据索引进行快速访问。
对于数组的增删方面,因为本身数组是连续的一段空间,因此如果是要删除中间的一个元素,那么就需要把剩下的元素都往前挪一位,这个操作太消耗性能,因此对于数组的曾删应该尽量操作数组的末尾元素。如果是要操作中部元素,那么挪位操作应尽量放在最后一步,也就是经过了一系列增加删除之后最后才进行挪位。
ArrayList源码
ArrayList底层是数组:
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
transient Object[] elementData;//这里的transient修饰词作用应该是防止序列化效果应该同HashMap
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {
}
然后是add操作
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
add方法里面重要的是第一个。
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
里面的calculateCapacity会进行计算然后判断,