ArrayLis扩容时:
-
检查是否需要扩容:在执行添加元素操作之前,ArrayList会检查当前元素数量是否已经达到了内部数组的容量。如果元素数量等于或超过了容量,就需要进行扩容操作。
-
计算新的容量:ArrayList会根据扩容规则计算出新的容量。通常情况下,新容量是当前容量的一定倍数(例如,通常是当前容量的1.5倍或2倍)。
-
创建新的内部数组:根据新的容量,ArrayList会创建一个新的内部数组,用于存储元素。新的数组的大小是根据计算得到的新容量确定的。
-
将元素复制到新数组:ArrayList会将当前内部数组中的元素逐个复制到新的内部数组中。这个过程会涉及将元素从旧数组内存空间复制到新数组内存空间,确保元素的顺序不变。
-
更新内部数组和元素数量:扩容完成后,ArrayList会将内部数组设置为新的数组,并更新元素数量属性为当前元素的个数。此时,ArrayList的容量属性也会更新为新的容量。
ArrayList<Integer> arrayList = new ArrayList<>(10); // 初始容量为10 // 添加元素到ArrayList arrayList.add(10); arrayList.add(20); arrayList.add(30); // 扩容操作 if (arrayList.size() >= arrayList.capacity()) { int newCapacity = arrayList.capacity() * 3/2; // 计算新容量1.5倍扩容 // int newCapacity = arrayList.capacity() * 2; // 计算新容量2倍扩容 arrayList.resize(newCapacity); // 创建新内部数组并复制元素 } // 扩容方法 private void resize(int newCapacity) { Object[] newArray = new Object[newCapacity]; // 创建新的内部数组 // 将元素从旧数组复制到新数组 for (int i = 0; i < arrayList.size(); i++) { newArray[i] = arrayList.get(i); } arrayList.array = newArray; // 更新内部数组为新数组 arrayList.capacity = newCapacity; // 更新容量为新容量 }
在Java中,ArrayList的扩容策略是相对灵活的,具体的扩容倍数会根据实际情况进行选择。默认情况下,当ArrayList需要进行扩容时,它会采用当前容量的1.5倍作为新的容量。
ArrayList采用1.5倍扩容的主要原因是在平衡内存空间的利用率和性能之间。通过选择1.5倍的扩容,可以在一定程度上减少频繁扩容的次数,同时也避免了过多的内存浪费。这种折中的策略在大多数情况下都能够提供较好的性能和内存利用率。
然而,也可以根据具体需求和场景选择不同的扩容倍数。有些情况下,可能会选择其他扩容倍数,例如2倍扩容。选择更大的扩容倍数可以减少扩容的频率,适用于存储大量数据且需要减少内存分配次数的情况。但这样做可能会造成一定的内存浪费。
可以通过调用
ArrayList
的构造函数,传递一个初始容量参数来控制初始容量的大小。这样可以避免在初始阶段进行频繁的扩容操作。例如,可以使用ArrayList(int initialCapacity)
构造函数指定初始容量。