动态数组合并应复用容器、控制扩容、减少中间对象:ArrayList 用 clear() 复用并预设容量;StringBuilder 用 setLength(0) 替代重建和 toString();批量操作优先 Collections.addAll 和 Arrays.asList;大数据量需分批处理,避免流式嵌套。

动态数组合并时避免频繁创建新对象,关键在于复用已有容器、控制扩容节奏、减少中间结果生成。Java 中的 ArrayList、StringBuilder 等都支持原地扩展和重置,只要不每次 new、不盲目调用 toString() 或 toArray(),就能大幅降低 Eden 区压力。
复用 ArrayList 实例,用 clear() 替代重建
合并多个小列表时,不要为每轮循环 new ArrayList,而是声明一次、多次 clear() 后复用:
- 将 ArrayList 提到循环外初始化,例如 ArrayList<String> merged = new ArrayList<>(1024);,预设足够容量可避免多次数组复制
- 每次合并前调用 merged.clear(),它只重置 size 字段,不释放底层数组内存,后续 add 直接覆盖或追加
- 注意:clear() 后若元素仍被外部引用,可能造成内存泄漏;确保旧元素不再被持有
拼接字符串用 StringBuilder.setLength(0),不 new 不 toString
当合并的是字符串片段(如日志行、SQL 参数、JSON 字段),StringBuilder 是最优选择:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 初始化时指定合理初始容量,比如 new StringBuilder(8192),避免 char 数组反复扩容
- 每次合并前调用 sb.setLength(0),比 sb.delete(0, sb.length()) 更轻量,直接截断逻辑长度
- 全程只在最终需要 String 时调用一次 toString(),此前所有 append 都在原数组上操作,零字符串对象产生
批量合并优先用 Collections.addAll 和 Arrays.asList
对已知大小的数组或固定集合,跳过逐个 add 的开销:
立即学习“Java免费学习笔记(深入)”;
- 用 Collections.addAll(targetList, array...) 一次性注入,比 for + add 少约 30% 方法调用开销
- Arrays.asList() 返回的是轻量包装器,不复制数据;若需可变列表,再传给 new ArrayList(...),但仅做一次
- 避免在循环里反复调用 Arrays.asList(item) —— 每次都新建一个内部 List 实现,虽小但高频下积少成多
大合并场景考虑流式处理或分批缓冲
当源数据量极大(如百万级记录合并),单次加载易触发 GC 抖动:
- 改用分批读取 + 批量写入,例如每次处理 5000 条,clear 复用 list,再 flush 到文件或数据库
- 避免用 Stream.concat 或 flatMap 做多层嵌套合并——每层都会生成中间 Spliterator 和 Pipeline 节点
- 如必须用流,优先使用原始类型流(IntStream / LongStream)或预构建 Collector,例如 Collectors.toCollection(() -> reusedList)

















