List在java中是一个有序集合(Ordered collection),他提供了对每一个插入元素的细粒度控制,通过整型索引使用者可以访问其中的每一个元素。List允许插入其中的元素重复,也可以插入null类型的值,同时,List实现了很多集合Collection接口中没有的方法。诸如,iterator、add、remove、, equals、hashCode。
1、基本的组织图
2、常见List实现的分析
a)ArrayList ,底层本质上是由数组实现元素的存储,源码中简单的定义了一个对象数组
private transient Object[] elementData;
备注: transient关键字 ArrayList的存储结构定义为transient,重写writeObject来实现自定义的序列化,优化了存 储。
源码中定义了一个整型变量记录实际有效元素的个数
private int size;
浏览ArrayList的源码,可以发现其中包括三个构造器,分别是:
public ArrayList() //无参构造器,默认初始化容量为10
public ArrayList(int initialCapacity) //提供了自定义容量的构造器
上边两个方法相当简单,仅仅是在判断入参合法后,new了一个对象数组.
public ArrayList(Collection<? extends E> c) //将指定的集合类型转换为ArrayList存储.
常用方法 add,remove,get,
add方法很简单,源码的实现如下
public boolean add(E e) {
ensureCapacityInternal(size + 1); // modCount加1,然后如果数组容量不足,增加容量
elementData[size++] = e; //在数组中添加元素
return true;
}
备注:modCount是在 AbstractList 中定义的,为全局变量,主要实现了ArrayList的fast-fail机制 参见fast-fail机制
add的变形版本,源码如下:
(1) 在list的指定位置插入元素
public void add(int index, E element) {
rangeCheckForAdd(index); //下标的合法性检查
ensureCapacityInternal(size + 1); // 检查数组容量是否充足
System.arraycopy(elementData, index, elementData, index + 1,
size – index); //将数组 elementData中的元素从指定索引处一次后移,当然这里 //size< elementData.length
elementData[index] = element;//实现插入操作
size++; //元素数量+1
}
(2) 在list的指定位置插入集合
public boolean addAll(int index, Collection<? extends E> c) {
rangeCheckForAdd(index); // 下标的合法性检查
Object[] a = c.toArray(); //转换为数组
int numNew = a.length; //待插入数组长度
ensureCapacityInternal(size + numNew); //检查数组容量是否充足
int numMoved = size – index; //需要移动的元素数目
if (numMoved > 0)
System.arraycopy(elementData, index, elementData, index + numNew,
numMoved); //将数组 elementData中的元素从指定索引处一次后移,当然这里 //size + numMoved< elementData.length
System.arraycopy(a, 0, elementData, index, numNew); //将元素填充到指定的位置序列
size += numNew; //元素数量增加
return numNew != 0;
}
自白:我本小虾,不想混沉度日,读写jdk源码以慰藉无所适从的灵魂,水平有限,如有失误,请诸位大神批评!