文章目录
(1)ArrayList所继承的接口
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable
ArrayList继承了 AbstractList 实现了List接口,RandomAccess接口,Cloneable接口
(2)ArrayList类所包含的属性
【1】serialVersionUID
serialVersionUID适用于Java的序列化机制,这个我们今天先不用过多考虑
private static final long serialVersionUID = 8683452581122892189L;
【2】DEFAULT_CAPACITY
初始的默认初始容量10
private static final int DEFAULT_CAPACITY = 10;
【3】EMPTY_ELEMENTDATA
空数组
private static final Object[] EMPTY_ELEMENTDATA = {};
【4】DEFAULTCAPACITY_EMPTY_ELEMENTDATA
这个也是一个空数组,但是区别是什么呢???
当第一个元素被加进来的时候DEFAULTCAPACITY_EMPTY_ELEMENTDATA 知道如何扩张,在之后的源码解析会再次解释。
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
【5】elementData
elementData数组用来存储ArrayList中的数据(ArrayList的底层数据结构是数组)
transient Object[] elementData;
【6】size
记录集合中所存储元素的个数
private int size;
(3)ArrayList集合中的方法
1> 构造方法
【1】ArrayList(int initialCapacity)
- 给定初始容量的ArrayList
- 初始容量不为空的时候创建初始容量大小的Object[],也就是说ArrayList底层用的是Object数组
- 初始容量为0的时候,直接返回 第一个空数组
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);
}
}
【2】ArrayList()
- 默认ArrayList无参构造返回DEFAULTCAPACITY_EMPTY_ELEMENTDATA空数组
- 第一次加入元素的时候,调用下面add()方法里确定了(扩容为)初始大小为10
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
【3】ArrayList(Collection<? extends E> c)
- 构造函数的参数是集合
- 原集合转化成数组
- 数组长度为0,就返回一个空集合
- 数组长度不为0,将原集合中的数据复制到新数组copyOf(要复制的数组,新数组的长度)
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> add(E e)方法
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
【1】ensureCapacityInternal()函数源码
- 如果当前数组elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA是个空数组
- 那就在默认大小10和参数minCapacity之中选择最大值也就是说默认大小就是10
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
【2】ensureExplicitCapacity(int minCapacity) 函数源码
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
3> add(int index, E element)方法
根据索引加入一个指定数据
- 先检查位置有效性(是否越界)
- 添加修改次数,判断是否需要扩容
- 完成数组自身从index开始的所有元素到index+1开始长度为size-index的位置上
- 将新元素添加至指定位置
public void add(int index, E element) {
//位置有效性检查
rangeCheckForAdd(index);
//添加修改次数,判断是否需要扩容
ensureCapacityInternal(size + 1); // Increments modCount!!
//完成数组自身从index开始的所有元素拷贝到index+1开始且长度为size-index的位置上。
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
//上面是完成自身的拷贝
//下面将add的这个数据添加到index位置上
elementData[index] = element;
size++;
}
private void rangeCheckForAdd(int index) {
if (index > size || index < 0)//是否越界鸭???
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
private String outOfBoundsMsg(int index) {
return "Index: "+index+", Size: "+size;
}
4> grow(int minCapacity) 扩容数组
- 旧容量右移一位再加上原大小即原大小的1.5倍
- 如果扩容过小,则至少扩容至minCapacity
- 如果扩容过大,则大小选择Integer.MAX_VALUE
- MAX_VALUE = 0x 7fff ffff
- 然后将旧数组中的数据复制到新数组中:copyOf()
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);//扩容至原大小的1.5倍
if (newCapacity - minCapacity < 0)//如果扩张的大小过小,则至少扩容至minCapacity
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)//如果扩容的大小过大,Integer.MAX_VALUE=MAX_VALUE = 0x 7fff ffff
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);//将数组中数据copyOf()到新的数组中
}
public static int[] copyOf(int[] original, int newLength) {
int[] copy = new int[newLength]; //创建一个新长度的数组
System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength));
return copy;
}
//public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length);
【1】 hugeCapacity(int minCapacity)源码
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}