一、Java 中 Map 遍历的常用方式
在开始前先说明:Map本身没有迭代器,我们通常通过获取它的键集 (keySet)、值集 (values)或键值对集 (entrySet)来实现遍历。以下是最常用的 5 种遍历方式,结合代码示例讲解。
1. 方式 1:遍历 keySet(仅获取键)
适合只需要 Map 的键(Key),不需要值(Value)的场景。
import java.util.HashMap; import java.util.Map; import java.util.Set; public class MapTraversal { public static void main(String[] args) { // 初始化一个测试 Map Map<String, Integer> map = new HashMap<>(); map.put("Java", 1); map.put("Python", 2); map.put("C++", 3); // 1. 遍历 keySet(仅获取键) Set<String> keySet = map.keySet(); for (String key : keySet) { System.out.println("键:" + key); } } }输出结果:
键:Java 键:Python 键:C++2. 方式 2:遍历 keySet + get (key)(获取键和值)
通过键获取值,是新手最容易想到的方式,但性能较差(因为每次get(key)都会重新计算哈希),不推荐在大数据量场景使用。
// 2. 遍历 keySet + get(key)(获取键和值) for (String key : map.keySet()) { Integer value = map.get(key); System.out.println("键:" + key + ",值:" + value); }输出结果:
键:Java,值:1 键:Python,值:2 键:C++,值:33. 方式 3:遍历 entrySet(推荐,高效获取键值对)
直接遍历entrySet(键值对集合),一次获取键和值,性能最优,是最推荐的方式。
// 3. 遍历 entrySet(高效获取键值对) for (Map.Entry<String, Integer> entry : map.entrySet()) { String key = entry.getKey(); Integer value = entry.getValue(); System.out.println("键:" + key + ",值:" + value); }输出结果:和方式 2 一致
4. 方式 4:遍历 values(仅获取值)
适合只需要 Map 的值,不需要键的场景。
// 4. 遍历 values(仅获取值) for (Integer value : map.values()) { System.out.println("值:" + value); }输出结果:
值:1 值:2 值:35. 方式 5:Lambda 表达式遍历(Java 8+)
Java 8 及以上版本支持,语法简洁,适合快速遍历。
// 5. Lambda 表达式遍历(Java 8+) map.forEach((key, value) -> { System.out.println("键:" + key + ",值:" + value); });输出结果:和方式 2/3 一致
6. 方式 6:迭代器遍历(支持边遍历边删除)
如果需要在遍历过程中删除元素,推荐使用迭代器(foreach 遍历中删除会抛出ConcurrentModificationException)。
// 6. 迭代器遍历(支持删除元素) import java.util.Iterator; Iterator<Map.Entry<String, Integer>> iterator = map.entrySet().iterator(); while (iterator.hasNext()) { Map.Entry<String, Integer> entry = iterator.next(); String key = entry.getKey(); Integer value = entry.getValue(); System.out.println("键:" + key + ",值:" + value); // 示例:删除键为 "Python" 的元素 if ("Python".equals(key)) { iterator.remove(); // 安全删除 } } System.out.println("删除后 Map:" + map); // 输出 {Java=1, C++=3}二、各遍历方式的对比
| 遍历方式 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| keySet | 仅遍历键,逻辑简单 | 无法直接获取值 | 只需要键的场景 |
| keySet + get(key) | 能获取键值,新手易理解 | 性能差(多次哈希计算) | 小数据量、临时遍历 |
| entrySet | 性能最优,能获取键值 | 语法稍复杂(对比 Lambda) | 大数据量、需要键值的核心场景 |
| values | 仅遍历值,逻辑最简单 | 无法获取键 | 只需要值的场景 |
| Lambda 表达式 | 语法简洁,代码量少 | Java 8+ 才支持,无法边遍历边删 | Java 8+、无需删除元素的场景 |
| 迭代器(Iterator) | 支持边遍历边删除,线程安全 | 代码稍繁琐 | 需要删除元素的场景 |
总结
- 优先推荐:日常开发中需要获取键值对时,优先使用
entrySet(性能最优)或 Lambda 表达式(语法简洁,Java 8+)。 - 特殊场景:只需要键用
keySet,只需要值用values;需要删除元素用迭代器。 - 避免使用:尽量不要用
keySet + get(key)遍历大数据量的 Map,性能损耗明显。