集合性能优化:容量预分配与调优
容量预分配
容量预分配可以减少扩容次数,提升性能:
java
// ❌ 默认容量,频繁扩容
List<String> list1 = new ArrayList<>();
// 10 万元素:~17 次扩容,每次都复制元素
// ✅ 预估容量,一次到位
List<String> list2 = new ArrayList<>(133334); // 100000/0.75 + 1
// ✅ HashMap 同理
Map<String, Object> map = new HashMap<>(133334);扩容次数对比
java
// 默认容量 16,负载因子 0.75
// 10 万元素扩容路径:
// 16 → 32 → 64 → 128 → 256 → 512 → 1024 → 2048 → 4096
// → 8192 → 16384 → 32768 → 65536 → 131072
// 13 次扩容!
// 预分配 133334:
// 约 133334/0.75 = 177778 → 2^18 = 262144
// 1 次扩容(或不扩容)预分配计算
java
// 预估元素数量:N
// HashMap:initialCapacity = (int)(N / 0.75) + 1
// ArrayList:initialCapacity = NLinkedHashSet 的 LRU 缓存
java
// 简单 LRU 缓存
LinkedHashMap<K, V> cache = new LinkedHashMap<>(16, .75f, true) {
@Override
protected boolean removeEldestEntry(Map.Entry eldest) {
return size() > maxSize;
}
};字符串去重(Intern)
java
String s1 = new String("hello");
String s2 = new String("hello");
s1.intern() == s2.intern() // true,共享常量池中的字符串集合转换为方法返回值
java
// ❌ 每次调用都创建新集合
public List<String> getItems() {
return new ArrayList<>(internalList);
}
// ✅ 返回不可变视图
public List<String> getItems() {
return Collections.unmodifiableList(internalList);
}总结
| 优化手段 | 说明 |
|---|---|
| 容量预分配 | 预估大小,减少扩容 |
| LinkedHashSet LRU | 自动淘汰 |
| 不可变返回 | 防止外部修改 |
