在本文中,我们将通过示例讨论在 Java 上遍历 HashMap 的几种方式。
1. 初始化 HashMap
首先新建 HashMap,代码如下:
HashMap<Integer,String> map = new HashMap<>();
map.put(1,"111");
map.put(2,"222");
map.put(3,"333");
2. 遍历
方式一:for-each循环 + entrySet()
entrySet()
返回的是一个包含映射关系(键值对)的集合 ,类型是 Map.Entry
。故可直接通过 getKey()
、getValue()
取出 key 和 value ,因此效率上采用 entrySet()
方式会更高。
Map 中采用 Entry 内部类来表示一个映射项,映射项包含 Key 和 Value , 每一个键值对也就是一个Entry。
for (Map.Entry entry : map.entrySet()){
System.out.println("key:" + entry.getKey() + ", " + "value:" + entry.getValue());
}
方式二:for-each循环 + keySet()
keySet()
返回的是一个 key 的集合。
keySet()
方式的遍历性能不如 entrySet()
,原因是 keySet()
会进行两次遍历:
- 第一次遍历是将所有的 key 放入到集合 Set 当中;
- 第二次遍历是根据 Set 中的 key 使用
get()
方法获取 value 值;
for (Integer key : map.keySet()){
System.out.println("key:" + key + ", " + "value:" + map.get(key));
}
方式三:for循环 + values()
values()
返回的是一个 value 的集合。
for (String value : map.values()){
System.out.println("value:" + value);
}
方式四:迭代器 + entrySet()
使用不带泛型的迭代器进行遍历:
Iterator itr = map.entrySet().iterator();
while (itr.hasNext()){
Map.Entry entry = (Map.Entry)itr.next();
System.out.println("key:" + entry.getKey() + ", " + "value:" + entry.getValue());
}
使用带泛型的迭代器进行遍历:
Iterator<Map.Entry<Integer, String>> entries = map.entrySet().iterator();
while (entries.hasNext()) {
Map.Entry<Integer, String> entry = entries.next();
System.out.println("key:" + entry.getKey() + ", value:" + entry.getValue());
}
方式五:迭代器 + keySet()
Iterator<Integer> itrKey = map.keySet().iterator();
while (itrKey.hasNext()){
Integer key = itrKey.next();
System.out.println("key:" + key + ", value:" + map.get(key));
}
方式六:forEach + Lambda表达式(Java8)
map.forEach((k, v) -> System.out.println("key:" + k + ", value:" + v));
方式七:Stream API
map.entrySet().stream().forEach((entry)->{
System.out.println("key:" + entry.getKey() + ", value:" + entry.getValue());
});
3. 总结
当键值对数量少的时候,entrySet()
和 keySet()
的性能差别不大。但是当数据量大时,entrySet()
比 keySet()
的性能高,原因如下:
keySet()
返回的是只存放 key 的 Set 集合。我们在使用 for-each 遍历该 Set 集合时,还需要在 for-each 中再使用get(key)
方法来获取每一个 key 对应的 value。主要差异就出现在这里:get(key)
方法获取 value 时需要遍历一次 HashMap 集合。entrySet()
返回的是存放 key-value 键值对的 Set 集合。所以我们在使用 for-each 遍历该集合时,可以直接从 Set 集合获得键值对,无须再去遍历 HashMap 获取 value 值。