【Java】HashMap 的遍历方式有哪些?哪种更高效?
HashMap的遍历方式有很多种,常见的包括基于KeySet、entrySet、values、Java8+的forEach。以及迭代器Iterator等。
一、常见的遍历方式及示例:
1.通过keySet()遍历(键->值)。
KeySet()
会返回所有的key的集合,遍历key后通过get(key)
获取对应的value。
示例:
HashMap<String, Integer> map = new HashMap<>();
map.put("a", 1);
map.put("b", 2);// 遍历 key,再获取 value
for (String key : map.keySet()) {Integer value = map.get(key);System.out.println("key: " + key + ", value: " + value);
}
2.通过entrySet()遍历 (键值对直接获取):
entrySet()返回所有的键值对(Map.Entry)的集合,每个Entry对象同时包含key和value,可直接获取。
for (Map.Entry<String, Integer> entry : map.entrySet()) {String key = entry.getKey();Integer value = entry.getValue();System.out.println("key: " + key + ", value: " + value);
}
3.通过values()遍历(仅遍历值)
values()仅返回所有的value的集合,适合只需要value的场景。
for (Integer value : map.values()) {System.out.println("value: " + value);
}
4.Java8+forEach遍历(结合Lambda):
Java 8为Map新增了forEach方法,可直接通过Lambda表达式遍历键值对,代码更简洁。
map.forEach((key, value) -> {System.out.println("key: " + key + ", value: " + value);
});
5.迭代器Iterator遍历:
// 迭代 entrySet
Iterator<Map.Entry<String, Integer>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {Map.Entry<String, Integer> entry = iterator.next();System.out.println("key: " + entry.getKey() + ", value: " + entry.getValue());// 安全删除(需通过迭代器的 remove 方法)if (entry.getKey().equals("a")) {iterator.remove();}
}
二、效率对比:
- entrySet()遍历效率>keySet()遍历效率。
- Java 8+的forEach与entrySet() 效率接近,但更简洁。
原因:
- keySet() 遍历需要两步操作:先遍历key,再通过get(key)获取value。而get(key) 方法需要重新计算key的哈希值,定位桶位置,若存在哈希冲突,还需要遍历链表/红黑树查找,额外消耗性能。
- entrySet()直接获取包含key和value的Entry对象,一次遍历即可同时拿到两者,无需额外的哈希计算和查找,减少了操作步骤,效率更高。
- Java8的forEach方法内部基于entrySet()实现(源码中通过迭代entrySet完成),因此效率与entrySet()相当,但代码更简洁。
适用场景:
- 若同时获取key和value:优先使用entrySet() 或 Java 8+ 的 forEach(推荐后者,代码更简洁)。
- 若仅需 value:使用 values()。
- 若需在遍历中删除元素,使用Iterator遍历entrySet(通过 iterator.remove() 安全删除,避免并发修改异常)。
总结:
- HashMap遍历的高效方式是entrySet() 或 Java 8+ 的 forEach,其中 forEach 兼具效率和简洁性,首选。
- keySet() 因额外的 get 操作,效率较低,不推荐优先使用。