HashMap 是Java开发中经常使用的数据结构。相信HashMap 的基本用法你已经很熟悉了。那么我们该如何遍历HashMap 呢?哪种遍历方式的性能更好呢?本篇文章来为你解决这个疑惑。

一、HashMap 遍历

如果你了解一些HashMap 底层原理,那么你肯定知道HashMap 是一个存储键值对的集合,每个键值对叫Entry。Entry 组成的数组构成了整个HashMap 的主干。Entry 的索引是通过Hash()方法计算出来的。因此Entry在数组内部是无序的(所以我们不能单纯的用for语句有序遍历)。那么我们该如何遍历HashMap 呢?

1. 使用EntrySet遍历

HashMap 的内部有一个EntrySet方法可以让我们方便地获取HashMap 数组内的所有Entry。假设我们有一个这样的HashMap。

HashMap<String,Integer> map=new HashMap<String,Integer>();

我们可以这样获取EntrySet。

Set<Entry<String, Integer>> entrySet=map.entrySet();

这样就得到了HashMap 中所有的Entry。获取Entry 之后遍历就简单多了。我们可以用foreach 语句遍历

Set<Entry<String, Integer>> entrySet=map.entrySet();
for (Entry<String, String> entry : entrySet) {
System.out.println(entry.getKey()+":"+entry.getValue());
}

或者使用迭代器的方式:

Iterator<Map.Entry<String, String>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, String> entry = iterator.next();
System.out.println(entry.getKey()+":"+entry.getValue());
}
2.使用KeySet 遍历

HashMap 中的KeySet方法可以将把Map中所有的键存入到set集合中。再根据get方法,就可以获取到每一个键对应的值。 使用KeySet 遍历的代码如下:

for (String key : map.keySet()) {
System.out.println(key+":"+map.get(key));
}

补充一点,如果你想获取Hashmap 中所有的value,你可以用values 方法。该方法返回一个包含所有value 的collection。

Collection<String> collection = map.values();
System.out.println(collection);

二、性能比较

网上对这两种遍历方法进行性能比较的文章有很多,我在此就不详细比较了。结论就是,使用EntrySet (也就是第一种方式)进行遍历的性能更好,无论你是使用foreach还是迭代器,只要你用的是EntrySet 的方式就可以。而KeySet的方式性能就很差,至于KeySet为什么性能很差,我们可以看看遍历KeySet 时用到的get() 方法的源码(JDK 1.6 ver)。

 public V get(Object key) {
if (key == null)
return getForNullKey();
int hash = hash(key.hashCode());
for (Entry<K,V> e = table[indexFor(hash, table.length)];
e != null;
e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
return e.value;
}
return null;
}

可以看出来,源码先获取了key 对应的hash值 ,然后根据hash值在HashMap 的Entry 数组内遍历出hash值与key的hash值相等的Entry,并返回对应的Value。所以get() 方法在获取Value 的时候又进行了一次循环,这导致了性能的下降。

三、总结

总结一下,我们介绍了两种遍历HashMap 的方法,一种是用EntrySet,另一种是用KeySet。性能上EntrySet 优于KeySet ,这是因为KeySet 的get方法在获取Value 的时候需要进行遍历。所以推荐遍历HashMap 的时候使用EntrySet 的方法。

HashMap 遍历的两种方式及性能比较的更多相关文章

  1. Java中HashMap遍历的两种方式

    Java中HashMap遍历的两种方式 转]Java中HashMap遍历的两种方式原文地址: http://www.javaweb.cc/language/java/032291.shtml 第一种: ...

  2. [Java] HashMap遍历的两种方式

    Java中HashMap遍历的两种方式原文地址: http://www.javaweb.cc/language/java/032291.shtml第一种: Map map = new HashMap( ...

  3. HashMap遍历的两种方式

    第一种: Map map = new HashMap(); Iterator iter = map.entrySet().iterator(); while (iter.hasNext()) {    ...

  4. HashMap遍历的两种方式,推荐使用entrySet()

    第一种: Map map = new HashMap(); Iterator iter = map.entrySet().iterator(); while (iter.hasNext()) {    ...

  5. python中字典的循环遍历的两种方式

    开发中经常会用到对于字典.列表等数据的循环遍历,但是python中对于字典的遍历对于很多初学者来讲非常陌生,今天就来讲一下python中字典的循环遍历的两种方式. 注意: python2和python ...

  6. C++ 数组遍历的两种方式

    C++ 数组遍历的两种方式: #include <iostream> using namespace std; int main() { // 一维数组 ] = {, , , , }; / ...

  7. Java中HashMap遍历的两种方法(转)

    第一种: Map map = new HashMap(); Iterator iter = map.entrySet().iterator(); while (iter.hasNext()) { Ma ...

  8. php对数组遍历的两种方式示例

    在对 php 数组遍历时,一般经常使用 foreach 来遍历,很少用 while 来遍历,在下面的代码中作一个对比. <?php $content = ["ID" => ...

  9. 【React】遍历的两种方式

    1.foreach(推荐) list.forEach((item)=>{ }); eg: dataSource.forEach((item) => { const est = item.e ...

随机推荐

  1. 谈谈后台服务的RPC和路由管理

    版权声明:本文由廖念波原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/147 来源:腾云阁 https://www.qclo ...

  2. 【文智背后的奥秘】系列篇——基于CRF的人名识别

    版权声明:本文由文智原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/133 来源:腾云阁 https://www.qclou ...

  3. Nodejs Web模块( readFile 根据请求跳转到响应html )

    index.js 根据请求的路径pathname,返回响应的页面. var http = require('http'); var fs = require('fs'); var url = requ ...

  4. C/C++程序编译流程

    单个文件的编译过程 多个文件的编译过程

  5. oracle如何四舍五入?

    转自:http://www.jb51.net/article/84924.htm 取整(向下取整): 复制代码代码如下: select floor(5.534) from dual;select tr ...

  6. Spring AOP依赖包

    Spring4和2.5发生了很大的变化,原来的spring2.5很多倚赖的jar包都是随着spring一起发布的,现在spring4已 经不再发布倚赖包,需要你自己去导入 1.org.springfr ...

  7. 问答项目---用户注册的那些事儿(PHP验证)

    JS 验证之后,还需要通过PHP验证: 提交过来的名称不一样,可以用字段映射: 在自动验证的时候,如果这个字段被映射,那么自动验证的时候,自动验证的就是 映射过后的字段: 控制器示例: //注册表单处 ...

  8. jquery收集表单数组及去掉字符串最后的逗号!

    jquery收集表单数组: <input type='text' name='one[]' value='' /><br> <input type='text' name ...

  9. java 中的& &&区别以及 C++ 中& &&的区别

    java中的 & &&两个运算符 (1).&在java中称做: 逻辑与 判断boolean类型,只有两者都是true时,才会返回true 举例: boolean b1= ...

  10. Ora-1157 ora-1110错误解决案例一枚

    1.数据库打开报错如下: SQL> alter database open; alter database open * ERROR at line 1: ORA-01157: cannot i ...