Java ArrayList 源码解析:add、remove、ensureCapacity、get 方法详解
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable { \n\n // 默认初始容量 \n private static final int DEFAULT_CAPACITY = 10; \n\n // 用于空实例共享的共享空数组实例 \n private static final Object[] EMPTY_ELEMENTDATA = {}; \n\n // 用于默认大小的空实例共享的共享空数组实例 \n private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; \n\n // 存储ArrayList元素的数组缓冲区 \n transient Object[] elementData; // 非私有以简化嵌套类访问 \n\n // ArrayList的大小(包含的元素数) \n private int size; \n\n // 构造一个具有指定初始容量的空列表 \n public ArrayList(int initialCapacity) { \n // 如果初始容量大于0,则初始化elementData数组为对应大小 \n if (initialCapacity > 0) { \n this.elementData = new Object[initialCapacity]; \n } \n // 否则,初始化elementData数组为EMPTY_ELEMENTDATA \n else if (initialCapacity == 0) { \n this.elementData = EMPTY_ELEMENTDATA; \n } \n // 如果初始容量小于0,则抛出IllegalArgumentException异常 \n else { \n throw new IllegalArgumentException("Illegal Capacity: " + \n initialCapacity); \n } \n } \n\n // 构造一个初始容量为10的空列表 \n public ArrayList() { \n this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; \n } \n\n // 添加一个元素到ArrayList的末尾 \n public boolean add(E e) { \n // 确保容量足够 \n ensureCapacityInternal(size + 1); // Increments modCount!! \n // 在elementData中添加元素 \n elementData[size++] = e; \n return true; \n } \n\n // 确保ArrayList的容量至少为minCapacity \n private void ensureCapacityInternal(int minCapacity) { \n // 如果elementData是共享空数组实例,则将其扩容为默认容量或者minCapacity中的较大值 \n if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { \n minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); \n } \n // 确保ArrayList的容量至少为minCapacity \n ensureExplicitCapacity(minCapacity); \n } \n\n // 确保ArrayList的容量至少为minCapacity \n private void ensureExplicitCapacity(int minCapacity) { \n // 修改次数加1 \n modCount++; \n\n // 如果minCapacity大于当前容量,则进行扩容操作 \n if (minCapacity - elementData.length > 0) \n grow(minCapacity); \n } \n\n // 对ArrayList进行扩容 \n private void grow(int minCapacity) { \n // 没有并发修改 \n int oldCapacity = elementData.length; \n // 扩容1.5倍 \n int newCapacity = oldCapacity + (oldCapacity >> 1); \n // 比较新容量和所需最小容量,取较大值 \n if (newCapacity - minCapacity < 0) \n newCapacity = minCapacity; \n // 比较新容量和最大数组容量,取较小值 \n if (newCapacity - MAX_ARRAY_SIZE > 0) \n newCapacity = hugeCapacity(minCapacity); \n // 将原有数据拷贝到新容量的数组中 \n elementData = Arrays.copyOf(elementData, newCapacity); \n } \n\n // 取两数的较大值,如果结果超过最大数组容量,则返回最大数组容量 \n private static int hugeCapacity(int minCapacity) { \n if (minCapacity < 0) // overflow \n throw new OutOfMemoryError(); \n return (minCapacity > MAX_ARRAY_SIZE) ? \n Integer.MAX_VALUE : \n MAX_ARRAY_SIZE; \n } \n\n // 获取ArrayList中指定索引处的元素 \n public E get(int index) { \n // 检查索引是否越界 \n rangeCheck(index); \n\n return elementData(index); \n } \n\n // 检查索引是否越界 \n private void rangeCheck(int index) { \n if (index >= size) \n throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); \n } \n\n // 返回索引越界异常的详细信息 \n private String outOfBoundsMsg(int index) { \n return "Index: " + index + ", Size: " + size; \n } \n\n // 从elementData中获取指定索引处的元素 \n E elementData(int index) { \n return (E) elementData[index]; \n } \n\n // 移除ArrayList中指定索引处的元素 \n public E remove(int index) { \n // 检查索引是否越界 \n rangeCheck(index); \n\n // 修改次数加1 \n modCount++; \n // 获取要移除的元素 \n E oldValue = elementData(index); \n\n // 计算要移动的元素个数 \n int numMoved = size - index - 1; \n // 如果numMoved大于0,则需要将后面的元素向前移动 \n if (numMoved > 0) \n System.arraycopy(elementData, index+1, elementData, index, \n numMoved); \n // 将最后一个元素置为null \n elementData[--size] = null; \n\n return oldValue; \n } \n\n // 清空ArrayList中的所有元素 \n public void clear() { \n // 修改次数加1 \n modCount++; \n\n // 将所有元素置为null \n for (int i = 0; i < size; i++) \n elementData[i] = null; \n\n // 将ArrayList的大小设为0 \n size = 0; \n } \n}
原文地址: https://www.cveoy.top/t/topic/qhaE 著作权归作者所有。请勿转载和采集!