<p>Java 8 的 Map.forEach() 方法通过 BiConsumer 实现简洁高效的键值对遍历,无需 entrySet() 或迭代器,直接传入 (key, value) -> { / 操作 / } 即可,语义清晰、性能最优、类型安全。</p>

Java 8 引入了 Map.forEach() 方法,它提供了一种简洁、函数式的方式遍历键值对,无需手动获取 entrySet() 或使用迭代器。
基本用法:直接传入 BiConsumer
forEach() 接收一个 BiConsumer super K, ? super V> 参数,即能同时处理键和值的函数式接口。最常用写法是用 Lambda 表达式:
map.forEach((key, value) -> System.out.println(key + " = " + value));- 等价于传统写法:
for (Map.Entry<K,V> e : map.entrySet()) { ... },但更简短清晰 - 注意:Lambda 参数名可任意命名(如
k和v),无需与 Map 声明类型一致
结合业务逻辑做条件处理
可在 Lambda 中嵌入判断或调用其他方法,避免额外循环:
- 只打印字符串类型的键对应的值:
map.forEach((k, v) -> { if (k instanceof String) System.out.println(v); }); - 更新另一个集合:
map.forEach((id, user) -> userList.add(user)); - 注意:Lambda 内部不能直接
return跳出整个 forEach,如需提前终止,应改用传统 for 循环
与 Stream 配合实现更复杂操作
forEach() 是终端操作,适合“消费”场景;若需过滤、映射等,建议转为 Stream:
立即学习“Java免费学习笔记(深入)”;
- 筛选并打印满足条件的键值对:
map.entrySet().stream().filter(e -> e.getValue() > 100).forEach(e -> System.out.println(e.getKey())); - 提取所有键为列表:
map.keySet().stream().collect(Collectors.toList()); - 不要混用:
map.forEach(...)本身不返回 Stream,无法链式调用中间操作
注意事项与常见误区
看似简单,但有些细节影响可读性和安全性:
- 空指针风险:如果 Map 本身为
null,调用forEach()会抛NullPointerException,建议先判空 - 并发修改:遍历时若其他线程修改 Map(非
ConcurrentHashMap),可能抛ConcurrentModificationException - 不适用于需要索引或顺序控制的场景(如只处理前 5 项),此时仍推荐增强 for 或迭代器


















