← 返回题目列表

数组里的 length、size 和 capacity 有什么区别?

高频 简单 第 4 / 30 题 更新于 2026/07/29
数组动态数组lengthcapacity

简化版

length 通常表示底层数组固定长度,size 表示当前已经存了多少元素,capacity 表示当前最多能装多少元素。静态数组常只有 length;动态数组对外看 size,对内维护 capacity,满了才扩容。

详细版

例如一个动态数组当前有 6 个元素,底层数组长度是 10,那么 size=6capacity=10,还能直接追加 4 个元素不用扩容。第 11 个元素到来时才需要申请更大数组并复制。

capacity: [ _ _ _ _ _ _ _ _ _ _ ] = 10
size:     [ x x x x x x ]         = 6

面试要强调:size 是逻辑元素数,capacity 是物理容量,length 在很多语言里是数组自身长度。把这三个概念混掉,就容易误判扩容、越界和内存占用。

完整版教学

一、三个词分别回答不同问题

lengthsizecapacity 看起来都像“长度”,但语义不同。

概念回答的问题例子
length底层数组长度是多少int[10].length = 10
size当前有效元素有几个ArrayList.size() = 6
capacity当前不扩容最多能放几个底层数组容量 10

记忆钩子:length 看数组本体,size 看已用多少,capacity 看还能撑多大。

二、静态数组主要看 length

静态数组创建后长度固定。比如 Java:

int[] a = new int[10];
System.out.println(a.length); // 10

这里 length 是数组对象的固定属性。即使你只给前 3 个位置赋了业务值,数组长度仍然是 10。

index:  0 1 2 3 4 5 6 7 8 9
value:  5 8 9 0 0 0 0 0 0 0
length = 10
logical used maybe = 3

如果业务只使用前 3 个位置,必须自己记录有效数量,否则默认值和真实数据容易混淆。

三、动态数组同时维护 size 和 capacity

动态数组底层仍然是数组,只是外面包了一层逻辑。

elementData capacity = 10
size = 6
valid range = [0, size)
unused range = [size, capacity)

追加元素时,如果 size < capacity,直接写到 elementData[size]。如果 size == capacity,才触发扩容。

if (size == elementData.length) {
  grow();
}
elementData[size++] = e;

这也是为什么尾部追加多数时候很快,只有偶尔扩容较贵。

四、区间边界要按 size 判断

动态数组对外暴露的是 size,不是底层数组的 capacity。遍历时应该到 size - 1,不能遍历到底层数组末尾。

for (int i = 0; i < list.size(); i++) {
  // 访问有效元素
}

如果误把 capacity 当 size,就会读到未使用区域。对于对象数组,未使用区域可能是 null;对于基本类型数组,可能是默认值 0、false 等。

这个错误在手写动态数组、队列、堆时很常见。

五、扩容判断看 size 和 capacity

扩容触发条件不是“length 变了”,而是“有效元素数达到容量”。以容量 4 的动态数组为例:

capacity = 4, size = 0: [ _ _ _ _ ]
add A -> size = 1: [ A _ _ _ ]
add B -> size = 2: [ A B _ _ ]
add C -> size = 3: [ A B C _ ]
add D -> size = 4: [ A B C D ]
add E -> grow, capacity maybe 6 or 8

单次扩容要复制旧元素,但因为不是每次都扩容,长期追加能做到均摊 O(1)。

六、删除后 size 变小,capacity 通常不变

动态数组删除元素后,size 会减少,但底层 capacity 通常不自动缩小。

before remove:
size = 6, capacity = 10

after remove:
size = 5, capacity = 10

这样做是为了避免频繁删加导致反复扩容缩容。如果确实长期少量元素占着大数组,可以提供 trim 或重新构建来释放空间。

面试里说清楚这一点,能顺便回答内存浪费和性能取舍。

七、常见误区与追问

  • 误区:size 和 capacity 是一回事。 size 是有效元素数,capacity 是底层可容纳上限。
  • 误区:数组 length 会随着添加元素变化。 普通数组 length 固定,动态数组变化的是逻辑 size。
  • 误区:删除元素后底层容量会自动变小。 多数动态数组不会自动缩容,以避免频繁分配和复制。
  • 追问:为什么遍历动态数组用 size? capacity 后面的区域不是有效元素,读出来可能是 null 或默认值。
  • 追问:扩容什么时候发生?size == capacity 且还要追加新元素时发生。
  • 追问:已知元素个数为什么要预设 capacity? 可以减少扩容次数和数组复制成本。

八、加强记忆

这三个词按“物理、逻辑、余量”来记:length 是底层数组物理长度,size 是当前逻辑元素个数,capacity 是不扩容能容纳的上限。静态数组主要看 length,动态数组对外看 size、对内看 capacity。扩容看 size == capacity,遍历看 i < size,删除通常只减 size 不降 capacity。