1 、ArrayList 简介
ArrayList 是一个数组队列,相当于 动态数组。与Java中的数组相比,它的容量能动态增长
2、ArrayList源码解读
2.1、 我们先来看一下 ArrAyList的结构
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable
继承自 AbstractList<E> ,这是一个抽象类对一些基础的list操作做了一些封装,实现了RandomAccess 标记接口,表明可以实现快速随机访问,Cloneable接口的实现表示该容器具有Clone函数操作,Serializable是序列化。
2.2、 一些成员变量
private static final long serialVersionUID = 8683452581122892189L; /** * 默认的数组大小 */ private static final int DEFAULT_CAPACITY = 10; /** * 空的实例数组 */ private static final Object[] EMPTY_ELEMENTDATA = {}; /** * 初始化时空的数组 */ private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; /** * arrayList 存蓄元素的数组 */ transient Object[] elementData; // non-private to simplify nested class access /** * 数组的大小 */ private int size;
2.3 构造方法
/** * 指定初始化数组的大小*/ 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); } } /** * 默认空的数组 */ public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; } /** *构造一个具有指定元素的ArrayList */ 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; } }
2.4 常用方法
增加操作 这里ArrayList扩充自己的容量是,扩充为以前的1.5倍 , 默认是 长度为10的数组
/** **/ public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; } /** *
*/ 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++; }
/**
* rangeCheckForAdd 判断下标是否越界(超过当前数组的大小)
*/
private void rangeCheckForAdd(int index) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
/**
* 判断数组的元素的是否初始化 , 当为空的构造方法的时候,初始化数组大小
*/
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
//判断是否需要扩容
ensureExplicitCapacity(minCapacity);
}
/**
* modCount 记录操作 这个参数运用到了 fail-fast 机制
*/
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
//扩容
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
/**
* 将整个数组size扩容为1.5倍
*/
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);
// 对数组进行复制处理
elementData = Arrays.copyOf(elementData, newCapacity);
}
删除
/** * 根据索引删除元素*/ public E remove(int index) { rangeCheck(index); modCount++;
// 获取元素 E oldValue = elementData(index); // 计算数组需要复制的数量
int numMoved = size - index - 1; if (numMoved > 0)
// 将index后的数据都向前移一位 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; }
/*
* 找到对应的元素后,删除。删除元素后的元素都向前移动一位
*/
private void fastRemove(int index) {
modCount++;
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
}
数组节约内存空间,缩小容量的方法 : trimToSize
/** * 数组缩小容量,增加元素会进行扩容,但删除元素没有缩容 这个方法是用来提供缩小数组容量
*/ public void trimToSize() { modCount++; if (size < elementData.length) { elementData = (size == 0) ? EMPTY_ELEMENTDATA : Arrays.copyOf(elementData, size); } }
本文参考 http://blog.csdn.net/u012883858/article/details/51393055
有什么不好的地方还望指正~~~