简述
上章简单介绍了什么是集合,集合有哪几种种类。
在这章中我们主要介绍Collection的其中一种实现方式,List。
什么是List
在上一章,我们已经了解了List主要分为3类,ArrayList, LinkedList和Vector。
为了进一步清晰List的结构,我在这手工画了一张图,用于回顾下
AbstarctCollection在上一张Java集合详解–什么是集合已经有简单的介绍,它是Collection接口的部分实现
1.List接口
首先看下List的官方定义
这段描述解决了许多公司经常问的两个问题List有什么特点和Set有什么区别。
上面清楚的说明了List是一个有序的集合,和set不同的是,List允许存储项的值为空,也允许存储相等值的存储项,还举了e1.equal(e2)的例子。
List是继承于Collection接口,除了Collection通用的方法以外,扩展了部分只属于List的方法。
从上图可以发现,List比Collection主要多了几个add(…)方法和remove(…)方法的重载,还有几个index(…), get(…)方法。
而AbstractList也只是实现了List接口部分的方法,和AbstractCollection是一个思路,这里就不具体介绍了,有兴趣的同学可以自行研究下。
2.ArraryList
ArrayList是一个数组实现的列表,由于数据是存入数组中的,所以它的特点也和数组一样,查询很快,但是中间部分的插入和删除很慢。我们来看几段关键的代码。
首先是ArrayList的类关系和成员变量
//ArrayList继承了Serializable并且申明了serialVersionUID,表示ArrayList是一个可序列化的对象,可以用Bundle传递
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
private static final long serialVersionUID = 8683452581122892189L;
/**
* Default initial capacity.
*/
private static final int DEFAULT_CAPACITY = 10;
/**
* Shared empty array instance used for empty instances.
*/
private static final Object[] EMPTY_ELEMENTDATA = {};
/**
* The array buffer into which the elements of the ArrayList are stored.
* The capacity of the ArrayList is the length of this array buffer. Any
* empty ArrayList with elementData == EMPTY_ELEMENTDATA will be expanded to
* DEFAULT_CAPACITY when the first element is added.
*/
//从这里可以看到,ArrayList的底层是由数组实现的,并且默认数组的默认大小是10
private transient Object[] elementData;
/**
* The size of the ArrayList (the number of elements it contains).
*
* @serial
*/
private int size;
然后是构造函数
//ArrayList有2个构造函数,一个是默认无参的,一个是传入数组大小的
//在JavaEffect书中明确提到,如果预先能知道或者估计所需数据项个数的,需要传入initialCapacity
//因为如果使用无参的构造函数,会首先把EMPTY_ELEMENTDATA赋值给elementData
//然后根据插入个数于当前数组size比较,不停调用Arrays.copyOf()方法,扩展数组大小
//造成性能浪费
/**
* Constructs an empty list with the specified initial capacity.
*
* @param initialCapacity the initial capacity of the list
* @throws IllegalArgumentException if the specified initial capacity
* is negative
*/
public ArrayList(int initialCapacity) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];
}
/**
* Constructs an empty list with an initial capacity of ten.
*/
public ArrayList() {
super();
this.elementData = EMPTY_ELEMENTDATA;
}
然后是add()操作
//首先看到,不过是指定index执行add操作,还是在尾部执行add操作,都会先确认当前的数组空间是否够插入数据
//并且从
//int oldCapacity = elementData.length;
//int newCapacity = oldCapacity + (oldCapacity >> 1);
//if (newCapacity - minCapacity < 0)
// newCapacity = minCapacity;
//看出,ArrayList默认每次都是自增50%的大小再和minCapacity比较,如果还是不够,就把当的
//size扩充至minCapacity
//然后,