核心思路是用 HashMap 查表替代内层查找型循环,将 O(n×m) 降为 O(n+m);关键识别内层是否为 equals/contains 等扫描操作;注意 key 非空、hashCode 合约及多值场景用 List/Set;辅以缓存 size、提取公共计算、外小内大等优化。

核心思路是把“循环内查找”变成“查表”,用空间换时间。最常用也最有效的手段,就是用 HashMap 替代内层遍历。
识别可优化的嵌套循环
不是所有嵌套循环都需要改。关键看内层循环在做什么:
- 如果是在扫描集合、逐个比较找匹配项(比如 user.getId().equals(order.getUserId())),这就是典型的“查找型嵌套”,适合优化
- 如果是在做真正的计算(比如矩阵乘法、动态规划状态转移),那得另选算法,HashMap 不适用
- 简单判断标准:内层循环里有没有 contains()、indexOf()、equals() 配合遍历 这类操作
用 HashMap 构建索引替代内层遍历
把原来 O(n×m) 的双重遍历,降为 O(n+m):
Java开发手册规约集合,基于阿里巴巴Java开发手册(嵩山版)。 涵盖7大维度:编程规约、异常日志、单元测试、安全规约、MySQL数据库、工程结构、设计规约。 当用户需要:(1) 编写或审查Java代码 (2) 检查命名/代码规范 (3) 处理异常和日志 (4) 编写单元测试 (5) 安全编码 (6) 数据库设...
- 先遍历一次内层数据(比如订单列表),以关联字段(如 userId)为 key,对象或集合为 value,存进 HashMap
- 再遍历外层数据(比如用户列表),直接用 map.get(userId) 拿结果,平均耗时 O(1)
- 注意:key 要确保非空且符合 equals/hashCode 合约;若一个 userId 对应多个订单,value 可用 List 或 Set
其他实用优化点
配合 HashMap 使用,效果更稳:
立即学习“Java免费学习笔记(深入)”;
- 提前缓存 size():避免 for (int i = 0; i < list.size(); i++) 这种写法,改成 int len = list.size(); for (int i = 0; i < len; i++)
- 提取循环无关计算:像 a * b 这种不依赖循环变量的表达式,一律提到循环外
- 外小内大原则:如果必须保留嵌套,把数据量小的放外层,减少内层重复执行次数
- 用 for-each 替代索引 for(当不需要下标时):语义清晰,JVM 通常能更好优化
别忽略数据结构本身的选择
HashMap 不是唯一解,根据场景灵活替换:
- 只判断存在性?用 HashSet 更轻量
- 需要按插入顺序遍历?用 LinkedHashMap
- 并发读多写少?考虑 ConcurrentHashMap,但注意它不保证全局遍历一致性
- key 是整数且范围可控?数组索引 比 HashMap 还快,零开销

















