ArrayList源码分析
add源码分析
如果是初始容量则为10
如果是扩容则为1.5倍扩容
elementData为容器长度
源码中变量的定义transient Object[] elementData; // non-private to simplify nested class access
private int size;
public boolean add(E e) {
ensureCapacityInternal(size + 1); // 扩容操作
elementData[size++] = e;
return true;
}
private void ensureCapacityInternal(int minCapacity) { //接收到1
//初始化容量,
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
//初始化得到10
ensureExplicitCapacity(10)
}
private static int calculateCapacity(Object[] elementData, int minCapacity) {
// private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
//从这里判断是否为第一次容量
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);//Math.max(10,1)计算下谁大谁小
//private static final int DEFAULT_CAPACITY = 10;
}
return minCapacity;
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++; //记录元素变化
// overflow-conscious code
if (minCapacity - elementData.length > 0) //10-0>0
grow(minCapacity);
}
private void grow(int minCapacity) { //minCapacity=10 扩容操作
// overflow-conscious code
int oldCapacity = elementData.length; //0
int newCapacity = oldCapacity + (oldCapacity >> 1);// 1.5倍扩容(oldCapacity >> 1)位运算相当于 oldCapacity /2 = 5 (oldCapacity >> 1=5)
if (newCapacity - minCapacity < 0) //0-10<0
newCapacity = minCapacity; //0=10
if (newCapacity - MAX_ARRAY_SIZE > 0)
// private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);//拷贝容量到容器
}
remove源码
/**
* Removes the element at the specified position in this list.
* Shifts any subsequent elements to the left (subtracts one from their
* indices).
*
* @param index the index of the element to be removed
* @return the element that was removed from the list
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
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; //返会得到的数组
}
//异常检查方法
private void rangeCheck(int index) {
if (index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
set源码
/**
* Replaces the element at the specified position in this list with
* the specified element.
*
* @param index index of the element to replace
* @param element element to be stored at the specified position
* @return the element previously at the specified position
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public E set(int index, E element) {
rangeCheck(index); //检查数组是否合法
E oldValue = elementData(index);//获取到原数组
elementData[index] = element; //把需要的放入数组
return oldValue; //返回数组
}
//异常检查方法
private void rangeCheck(int index) {
if (index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
get源码
/**
* Returns the element at the specified position in this list.
*
* @param index index of the element to return
* @return the element at the specified position in this list
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public E get(int index) {
rangeCheck(index); //异常检查
return elementData(index); //返回指定数据
}
//异常检查方法
private void rangeCheck(int index) {
if (index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}