接口返回了一个 Map,要把键值挨个打进日志;或者统计完词频,想把结果排出来看看。Map 不能按下标循环,写法和 List 不一样,Java 里常见就四种。

Java 的几种遍历写法

最推荐 entrySet,一次循环同时拿到键和值:

for (Map.Entry<Integer, String> e : map.entrySet()) { System.out.println(e.getKey()); System.out.println(e.getValue()); }

只要键就用 keySet,拿到键后再用 get 取值,等于查了两遍哈希表,数据量大时比 entrySet 慢;只要值直接 values()。JDK 8 以后还能一行搞定:

map.forEach((k, v) -> System.out.println(k));

挑写法就一条:要键要值用 entrySet 或 forEach,纯取值用 values,别用 keySet 再 get 绕远路。

遍历中想删元素,别踩这个坑

在增强 for 循环里直接调 map.remove,会抛 ConcurrentModificationException,集合不允许边遍历边改结构。正确做法是拿迭代器,边走边用迭代器自己的 remove 方法删;或者先收集要删的键,循环结束后统一删,两种都行。

顺序问题也留意下

HashMap 遍历出来的顺序和放进去的顺序没关系,要按插入顺序输出就换 LinkedHashMap,要按键排序就用 TreeMap。测试时发现顺序对不上,先查这三个类用没用对,别急着怀疑遍历写法。

前端 JS 的 Map 顺带说说

JavaScript 里的 Map 用 for...of 配 entries() 遍历,或者直接 forEach,注意回调参数先是值后是键,跟 Java 反着,两边切换容易搞混:

for (const [k, v] of m.entries()) { console.log(k, v); }

日常开发里,这几种写法覆盖了 map循环遍历 的绝大多数场景,记住 entrySet 是主力、删除靠迭代器、顺序看实现类,基本就不会出幺蛾子。