Java中遍历HashMap的方法

Java中遍历HashMap的方法

在Java中,有多种方式可以遍历HashMap。由于所有的映射(Map)都实现了Map接口,以下这些技术适用于任何Map的实现类,如HashMapTreeMapLinkedHashMapHashtable等。下面将介绍几种常见的遍历方法,并分析它们的优缺点。

实现步骤

方法一:使用For-Each循环遍历键值对

这是最常见的方法,在大多数情况下是首选。如果在循环中需要同时获取键和值,就可以使用此方法。

1
2
3
4
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
}

需要注意的是,For-Each循环是在Java 5中引入的,因此该方法仅适用于较新的Java版本。此外,如果尝试遍历一个null的映射,For-Each循环会抛出NullPointerException,所以在遍历之前应该始终检查空引用。

方法二:使用For-Each循环遍历键或值

如果只需要映射中的键或值,可以分别遍历keySetvalues,而不是entrySet

1
2
3
4
5
6
7
8
9
10
11
Map<Integer, Integer> map = new HashMap<Integer, Integer>();

// 仅遍历键
for (Integer key : map.keySet()) {
System.out.println("Key = " + key);
}

// 仅遍历值
for (Integer value : map.values()) {
System.out.println("Value = " + value);
}

这种方法比entrySet遍历有轻微的性能优势(大约快10%),并且代码更简洁。

方法三:使用迭代器(Iterator)遍历

使用泛型

1
2
3
4
5
6
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
Iterator<Map.Entry<Integer, Integer>> entries = map.entrySet().iterator();
while (entries.hasNext()) {
Map.Entry<Integer, Integer> entry = entries.next();
System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
}

不使用泛型

1
2
3
4
5
6
7
8
Map map = new HashMap();
Iterator entries = map.entrySet().iterator();
while (entries.hasNext()) {
Map.Entry entry = (Map.Entry) entries.next();
Integer key = (Integer)entry.getKey();
Integer value = (Integer)entry.getValue();
System.out.println("Key = " + key + ", Value = " + value);
}

也可以使用相同的技术来遍历keySetvalues。这种方法看起来可能有些冗余,但它有自己的优势。首先,它是在较旧的Java版本中遍历映射的唯一方法。另一个重要的特性是,它是唯一允许在迭代过程中通过调用iterator.remove()方法从映射中移除条目的方法。如果在For-Each迭代过程中尝试这样做,根据Javadoc的说法,会得到“不可预测的结果”。从性能角度来看,这种方法与For-Each迭代相当。

方法四:遍历键并查找值(效率较低)

1
2
3
4
5
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for (Integer key : map.keySet()) {
Integer value = map.get(key);
System.out.println("Key = " + key + ", Value = " + value);
}

这种方法看起来可能是方法一的更简洁的替代方案,但实际上它非常慢且效率低下,因为通过键获取值可能需要花费较长时间(在不同的Map实现中,这种方法比方法一慢20% - 200%)。如果安装了FindBugs,它会检测到这种情况并警告你迭代效率低下,因此应该避免使用这种方法。

最佳实践

  • 如果只需要映射中的键或值,使用方法二。
  • 如果使用的是较旧版本的Java(小于5)或计划在迭代过程中移除条目,则必须使用方法三。
  • 否则,使用方法一。

常见问题

  • NullPointerException:在使用For-Each循环遍历映射时,如果映射为null,会抛出NullPointerException。因此,在遍历之前应该检查映射是否为null
  • 并发修改异常:在使用For-Each循环遍历映射时,如果尝试在循环中修改映射(如移除条目),会得到不可预测的结果。如果需要在迭代过程中修改映射,应该使用迭代器的remove()方法。

Java中遍历HashMap的方法
https://119291.xyz/posts/2025-05-09.java-hashmap-iteration-methods/
作者
ww
发布于
2025年5月9日
许可协议