ArrayList源码分析
Posted liycode
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ArrayList源码分析相关的知识,希望对你有一定的参考价值。
1、成员变量
private static final int DEFAULT_CAPACITY = 10;
private static final Object[] EMPTY_ELEMENTDATA = {};
transient Object[] elementData;
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;
}
2、get()方法
public E get(int index) {
rangeCheck(index);
return elementData(index);
}
// 检查数组下标是否越界
private void rangeCheck(int index) {
if (index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
E elementData(int index) {
// 根据索引直接返回数组中的元素
return (E) elementData[index];
}
3、set()方法
public E set(int index, E element) {
rangeCheck(index); // 检查数组下标是否越界
E oldValue = elementData(index);
elementData[index] = element;
return oldValue;
}
4、add()方法
/**
* 在数组末尾插入元素
*/
public boolean add(E e) {
ensureCapacityInternal(size + 1);
elementData[size++] = e;
return true;
}
/**
* 在指定位置插入元素
*/
public void add(int index, E element) {
rangeCheckForAdd(index);
ensureCapacityInternal(size + 1); // Increments modCount!!
// 将数组中的元素从index开始,全部向后移动一个位置
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}
/**
* 处理数组容量与扩容
*/
private void ensureCapacityInternal(int minCapacity) {
// 判断是不是默认空数组
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); // 设置容量
}
ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// 判断容量是否大于实际的数组长度
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
private void grow(int minCapacity) {
int oldCapacity = elementData.length; // 老容量
int newCapacity = oldCapacity + (oldCapacity >> 1); // 新容量 = 老容量 + 老容量的一半
if (newCapacity - minCapacity < 0)
// 初始化时newCapacity=0
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0) // 扩容后超过了最大数组容量
// 实际数组的长度+1 > MAX_ARRAY_SIZE 返回Integer.MAX_VALUE否则返回MAX_ARRAY_SIZE
newCapacity = hugeCapacity(minCapacity); // 最大是Integer.MAX_VALUE
// 复制数组,对多只能复制前Integer.MAX_VALUE个
elementData = Arrays.copyOf(elementData, newCapacity);
}
未完,待续...
以上是关于ArrayList源码分析的主要内容,如果未能解决你的问题,请参考以下文章
Android 插件化VirtualApp 源码分析 ( 目前的 API 现状 | 安装应用源码分析 | 安装按钮执行的操作 | 返回到 HomeActivity 执行的操作 )(代码片段
Android 逆向整体加固脱壳 ( DEX 优化流程分析 | DexPrepare.cpp 中 dvmOptimizeDexFile() 方法分析 | /bin/dexopt 源码分析 )(代码片段