ArrayList
继承自AbstractList,实现了List、Cloneable、RandomAccess(随机访问,通常是常数时间)、Serializable共四个接口。其底层实现是数组,所以对数组下标的访问的速度是很快的。
源码解析
/**
*继承自AbstractList,实现了List、Cloneable、
*RandomAccess(随机访问,通常是常数时间)、Serializable共四个接口
*/
public class ArrayList extends AbstractList
implements List, RandomAccess, Cloneable, java.io.Serializable {
/**
* 实现了Serializable,序列号
*/
private static final long serialVersionUID = 8683452581122892189L;
/**默认的初始容量10
*
*/
private static final int DEFAULT_CAPACITY = 10;
/**
* 用于空实例的共享空数组实例。
*/
private static final Object[] EMPTY_ELEMENTDATA = {};
/**
* 数组缓冲区,arraylist的容量就是这个缓冲区的长度
*/
transient Object[] elementData;
/**
* ArrayList实际包含元素的数量
*
*/
private int size;
/**
* 带有初始容量大小的构造函数
*/
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
/**
* 空的构造函数,初始容量为10
*/
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
/**
* 创建一个包含collection的构造函数,并且最后将collection向上转型为Object
*
*/
public ArrayList(Collection extends E> c) {
elementData = c.toArray();
if ((size = elementData.length) != 0) {
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else {
// replace with empty array.
this.elementData = EMPTY_ELEMENTDATA;
}
}
/**
* 调整ArrayList实例的容量为当前大小。程序可以使用该方法来减少多余的存储空间
*/
public void trimToSize() {
modCount++;
if (size < elementData.length) {
elementData = (size == 0)
? EMPTY_ELEMENTDATA
: Arrays.copyOf(elementData, size);
}
}
/**
* 增加ArrayList的容量,如果增加的小于默认最小的,则使用默认最小容量
* @param minCapacity the desired minimum capacity
*/
public void ensureCapacity(int minCapacity) {
int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
// any size if not default element table
? 0
// larger than default for default empty table. It's already
// supposed to be at default size.
: DEFAULT_CAPACITY;
if (minCapacity > minExpand) {
ensureExplicitCapacity(minCapacity);
}
}
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
/**
* 数组的最大分配数量
*/
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
/**
* 增加容量,以确保它可以至少持有由最小容量参数指定的元素的数目
* @param minCapacity 所需的最小容量
*/
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
/**
* 根据最小容量判断返回容量(对比list极限容量)
*/
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
/**
* Returns the number of elements in this list.
* 返回list中元素的个数
* @return the number of elements in this list
*/
public int size() {
return size;
}
/**
* 判断list是否为空
*/
public boolean isEmpty() {
return size == 0;
}
/**
* 是否包含元素o
*/
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
/**
* 返回元素所在位置
*/
public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
/**
* 数组中可能包含N个相同元素,返回从后查找出来的元素位置
*/
public int lastIndexOf(Object o) {
if (o == null) {
for (int i = size-1; i >= 0; i--)
if (elementData[i]==null)
return i;
} else {
for (int i = size-1; i >= 0; i--)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
/**
* 进行浅克隆,元素并不被复制
*/
public Object clone() {
try {
ArrayList> v = (ArrayList>) super.clone();
v.elementData = Arrays.copyOf(elementData, size);
v.modCount = 0;
return v;
} catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable
throw new InternalError(e);
}
}
/**
* 返回list中全部元素的数组形式
*/
public Object[] toArray() {
return Arrays.copyOf(elementData, size);
}
/**
* Appends the specified element to the end of this list.
* 向尾部添加元素
* 这里要多说几句,很多人都是经常错误的比较 linkedlist和arraylist的add操作,比如循环的添加1千条数据
* 最后得到的结果却是arraylist更快一点,其实这种比较是错误的,arraylist的add方法其实是向尾部添加元素所以要快
* arraylist实现了random接口,访问是速度非常快的。但是随机存取的情况下,linkedList的速度其实是要更快的
* 然而就是这个操作其实才能对的上大家经常看的面试“圣经”里说的linkedList要更适用于频繁插入和删除
* 唠叨不嫌多,请记住ArrayList的底层实现是数组,而LinkList的底层实现是链表;
* 从ArrayList中随机删除一个对象,后面的数组排序就会朝前移位,这就是开销大的来处;而LinkList,
* 用的是链表,随机删除某一个,就将删除前的一个直接链接删除后的一个,而不要进行移位
* @param e element to be appended to this list
* @return true (as specified by {@link Collection#add})
*
*/
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
/**
* 指定位置插入元素(这个操作相当的耗时),尤其是System.arraycopy这个操作相当耗时
*/
public void add(int index, E element) {
rangeCheckForAdd(index);
ensureCapacityInternal(size + 1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}
/**
* 删除list中指定位置的元素,并将后边的元素向左移。(下标减1)
*/
public E remove(int index) {
rangeCheck(index);
modCount++;
E oldValue = elementData(index);
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
return oldValue;
}
/**
* 删除第一个指定的元素
*/
public boolean remove(Object o) {
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
}