size表示当前实际元素个数,capacity指底层数组能容纳的上限;size是所有集合共有的逻辑计数,capacity仅存在于ArrayList、HashMap等基于数组且支持扩容的实现中,且不对外暴露。

在Java集合中,“size”和“容量”是两个完全不同的概念,容易混淆但必须分清:size表示当前实际存了多少元素,而容量(capacity)指的是底层容器(如数组)能容纳多少元素而不触发扩容——它只对部分集合(如ArrayList、HashMap)有意义,且不对外直接暴露。
size 是实时可查的实际元素个数
size() 是所有 Collection 接口实现类都有的方法,返回当前集合中已添加的元素数量。它不依赖底层结构,也不涉及内存分配,纯粹是逻辑计数。
- 添加一个元素,
size()就加1;删除一个,就减1 - 即使底层数组还空着一大半,
size()只反映“用了多少” - 对
LinkedList、TreeSet等无固定容量概念的集合,size 就是唯一“大小”指标
容量是底层存储结构的物理上限
容量不是接口规范,而是具体实现的内部属性。只有基于数组实现、且支持动态扩容的集合(如 ArrayList、ArrayDeque、HashMap)才存在容量概念,且通常不提供 public 的 getCapacity() 方法。
-
ArrayList的容量 = 内部Object[] elementData数组的长度 -
HashMap的容量 = 桶数组(Node[] table)的长度,总是2的幂次 - 容量 ≥ size,但两者没有固定比例关系;容量可能远大于 size(比如刚 new 出来未添加元素)
扩容机制:容量不够时自动增长
当添加元素导致 size == 容量 时,多数集合会触发扩容,重新分配更大的底层数组,并复制原有数据。这是性能敏感操作,应尽量避免频繁发生。
立即学习“Java免费学习笔记(深入)”;
-
ArrayList默认初始容量为10,扩容公式:新容量 = 旧容量 × 1.5(即oldCapacity + (oldCapacity >> 1)) -
HashMap初始容量为16,扩容阈值 = 容量 × 负载因子(默认0.75),即 size 达到12时触发扩容,新容量翻倍 - 可通过构造函数预设合理初始容量(如
new ArrayList(100)),减少运行时扩容次数
怎么查看或估算容量?
Java 不提供标准 API 获取容量,但有间接方式:
- 对
ArrayList:可通过反射读取elementData.length(仅限调试/监控,生产慎用) - 对
HashMap:同样可反射获取table.length;或通过size()和loadFactor反推近似当前容量(例如 size=30,负载因子0.75 → 当前容量至少为40,实际可能是64) - 更实用的做法是:根据业务数据规模,在创建时显式指定初始容量,把容量控制权掌握在自己手里










