ArrayList底层是数组结构的,数组的默认长度为10。当数组添加满了后,会自动扩容为1.5倍。
原理讲解:
1.用空参构造函数创建ArrayList集合容器。
-
测试代码:
-
public class ArrayListDemo { public static void main(String[] args) { //创建ArrayList集合容器 ArrayList<String> list = new ArrayList<>(); } }
-
-
ArrayList部分源码:
-
//成员变量 //ArrayList底层的数组,如果使用 ArrayList 的默认构造器时(默认构造器就是创建集合容器时不带参数),它的初始容量就是 0 transient Object[] elementData; //定义一个空数组,空参构造器返回该数组,以及扩容的时候用到 private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; //空参构造函数 public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; }
-
空参构造函数里把一个空数组赋值给集合底层的数组。
-
结论:如果只是创建了集合容器,没有进行过添加操作,底层数组的默认长度为0。
2.往集合容器里面添加一个元素
-
测试代码:
-
public class ArrayListDemo { public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); //添加一个元素“张三” list.add("张三"); } }
-
-
ArrayList部分源码:
-
//成员变量 //ArrayList 的默认初始容量,如果没有显式指定容量,则使用这个值 private static final int DEFAULT_CAPACITY = 10; //定义一个空数组,空参构造器返回该数组,以及扩容的时候用到 private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; //size 是当前 ArrayList 中的元素数量,初始化为 0 private int size; //ArrayList底层的数组,如果使用 ArrayList 的默认构造器时(默认构造器就是创建集合容器时不带参数),它的初始容量就是 0 transient Object[] elementData; // 是一个常量,表示可以创建的最大数组大小 //Integer.MAX_VALUE 是 2^31 - 1,即最大的正整数。减去 8 是为了留出一些空间,避免在某些情况下(如内存分配)出现溢出或其他问题 private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; --------------------------------------------------------------------- //add方法 public boolean add(E e) { //将元素 e 添加到 ArrayList 中 //这个方法用于确保 ArrayList 有足够的容量来存储新添加的元素 ensureCapacityInternal(size + 1); // 会将元素 e 放到 elementData 数组的索引size位置(例如:添加第一个元素时,就是把元素放到0号索引位置),然后再把size的长度加1 elementData[size++] = e; return true; //该方法总是返回true(异常除外),表示元素成功添加到ArrayList中 } --------------------------------------------------------------------- //ensureCapacityInternal方法,add方法里面调用了该方法 //minCapacity表示所需的最小容量 private void ensureCapacityInternal(int minCapacity) { //ensureExplicitCapacity方法负责调整内部数组的实际容量 //calculateCapacity方法负责计算所需新容量 //elementData:当前数组 ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); } ---------------------------------------------------------------------- //calculateCapacity方法,ensureCapacityInternal方法里调用了该方法 //计算所需新容量 private static int calculateCapacity(Object[] elementData,int minCapacity) { //检查 elementData 是否为空的默认数组 if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { //如果是,返回默认容量和所需最小容量中的较大值 return Math.max(DEFAULT_CAPACITY, minCapacity); } //否则,返回所需的最小容量 return minCapacity; } ----------------------------------------------------------------------- //ensureExplicitCapacity方法,ensureCapacityInternal方法里调用了该方法 //调整内部数组的实际容量 private void ensureExplicitCapacity(int minCapacity) { //增加修改计数 modCount++; //modCount是为了确保集合在被迭代时的安全性和一致性 //如果所需容量大于当前数组长度,则调用 grow 方法 //即minCapacity如果大于当前数组的长度(elementData.length),则说明当前数组容量不足以容纳所需的最小容量,需要扩容 if (minCapacity - elementData.length > 0) grow(minCapacity); //调用 grow 方法来扩展数组的容量 } ----------------------------------------------------------------------- //grow方法,ensureExplicitCapacity方法里调用了该方法 //扩展内部数组 elementData 的容量,以确保它能够容纳至少 minCapacity 个元素 private void grow(int minCapacity) { int oldCapacity = elementData.length; // 获取旧容量(即元素的数量) //利用位移运算符'>>'计算旧容量的 1.5 倍 //oldCapacity >> 1 : oldCapacity 的二进制向右移动一位,从而实现除以2的效果, 相当于oldCapacity/2, int newCapacity = oldCapacity + (oldCapacity >> 1); //计算新容量 //如果计算出的新容量小于所需的最小容量 minCapacity,则将新容量设置为 minCapacity if (newCapacity - minCapacity < 0) //确保新容量满足最小需求: newCapacity = minCapacity; //检查新容量(newCapacity)是否超过了最大数组大小 MAX_ARRAY_SIZE //如果超过,则调用 hugeCapacity 方法来处理这种情况,通常是为了避免内存溢出 if (newCapacity - MAX_ARRAY_SIZE > 0) //限制最大容量 newCapacity = hugeCapacity(minCapacity); // 使用 Arrays.copyOf 方法创建一个大小为 newCapacity的新数组,并将 elementData 中的所有元素复制到新数组中。elementData 引用被更新为指向这个新数组 elementData = Arrays.copyOf(elementData, newCapacity); //复制数组 } ---------------------------------------------------------------------- //hugeCapacity方法,grow方法里调用了该方法 //这个方法用于处理非常大的数组容量 private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // 检查最小容量是否为负数 throw new OutOfMemoryError(); // 如果是,抛出内存不足错误 //三元表达式 return (minCapacity > MAX_ARRAY_SIZE) ? //如果所需容量超过最大数组大小 Integer.MAX_VALUE : // 如果是,就返回最大整数值,表示无法满足需求 MAX_ARRAY_SIZE; // 否则,返回最大数组大小 }
-