priorityqueue底层使用object[]数组,扩容采用混合策略:容量> 1)(即约1.5倍)增长,≥64时仍为1.5倍,非2倍;默认初始容量为11,插入第12个元素时扩容至16。

Java 的 PriorityQueue 底层使用的是**可变长数组(Object[] queue)**,其扩容机制并非固定倍数增长,而是采用“**小容量时加固定值、大容量时按 1.5 倍增长**”的混合策略。尤其在初始容量较小(如默认 11 或手动设为较小值)时,它**不会按 2 倍扩容,而是每次增加约原容量的一半(向上取整),即等效于 ×1.5**。
初始容量为 11 时的首次扩容行为
当你不指定初始容量(new PriorityQueue()),队列初始化容量为 11。当插入第 12 个元素触发扩容时:
- 计算新容量:
oldCapacity + (oldCapacity >> 1)→11 + (11 >> 1) = 11 + 5 = 16 - 实际扩容后数组长度变为 16(不是 22)
- 这是典型的“1.5 倍”增长(11 × 1.5 ≈ 16.5 → 向下取整得 16)
小容量下的通用扩容公式
只要当前容量 oldCap ,扩容逻辑统一为:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 新容量 = oldCap + (oldCap >> 1)(即 oldCap × 1.5,向下取整)
- 例如:容量为 1 → 扩为 1+0=1(不扩);容量为 2 → 扩为 2+1=3;容量为 7 → 扩为 7+3=10;容量为 63 → 扩为 63+31=94
- 注意:该公式在
oldCap == 0时特殊处理为 1(避免位运算异常)
何时切换到“至少加 1”的保守策略?
只有当 oldCap >= 64 时,扩容才改用更保守的公式:newCap = oldCap + (oldCap >> 1) 依然适用,但此时数值较大,×1.5 效果更稳定;而真正“非倍增”的情况只出现在边界——比如 oldCap=0 或扩容后仍不够用时,会 fallback 到 newCap = oldCap + 1,但这是极少数兜底场景,日常几乎遇不到。
为什么不用 2 倍?
设计者权衡了内存浪费与扩容频次:
- 2 倍扩容在小容量时浪费明显(如从 11→22,多占 11 个引用空间)
- 1.5 倍在增长速度和空间效率间取得更好平衡,实测对典型使用模式更友好
- 该策略与
ArrayList完全一致(JDK 7+),保证集合类行为一致性
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










