`
dingjob
  • 浏览: 181139 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

遍历map 哪种方式更加高效。

阅读更多

场景:偶尔生产环境的某台机器CPU使用率很高,经过定位发现是有一个大的HashMap(HashMap里面存放了大量数据,比如1W条)做循环引起的。

代码中采用了如下的遍历

 

for(Iterator ite = map.keySet().iterator(); ite.hasNext();){
  Object key = ite.next();
  Object value = map.get(key);
}

 

  通过Map类的get(key)方法获取value时,会进行两次hashCode的计算,消耗CPU资源;而使用entrySet的方式,map对象会直接返回其保存key-value的原始数据结构对象,遍历过程无需进行错误代码中耗费时间的hashCode计算;这在大数据量下,体现的尤为明显。

以下是HashMap.get()方法的源码:

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;
    }

 

 

正确用法如下:

 

for(Iterator ite = map.entrySet().iterator(); ite.hasNext();){
  Map.Entry entry = (Map.Entry) ite.next();
  entry.getKey();
  entry.getValue();
}

 

 

对比测试

 

public class HashMapTest {
    public static void getFromMap(Map map){
        for(Iterator ite = map.keySet().iterator(); ite.hasNext();){
            Object key = ite.next();
            Object value = map.get(key);
        }
    }
    public static void getFromMapByEntrySet(Map map){
        for(Iterator ite = map.entrySet().iterator(); ite.hasNext();){
            Map.Entry entry = (Map.Entry) ite.next();
            entry.getKey();
            entry.getValue();
        }
    }

    public static void main(String[] args) {
        Map map = new HashMap();
        for(int i=0;i<200000;i++){
            map.put("key"+i, "value"+i);
        }
        long currentTime = System.currentTimeMillis();
        getFromMap(map);
        long currentTime2 = System.currentTimeMillis();
        getFromMapByEntrySet(map);
        long currentTime3 = System.currentTimeMillis();
        System.out.println(currentTime2-currentTime);
        System.out.println(currentTime3-currentTime2);
    }

}

 

运行结果:

 

 

 

16
0

 

 

经过对比,可以看到明显的差别。

还有一种最常用的遍历方法,其效果也不太好,不建议使用

 

for(Iterator i = map.values().iterator(); i.hasNext();)   {       
            Object temp =  i.next();   
}  

 

 

 

分享到:
评论
2 楼 bailiyi 2014-05-13  
为什么要用Iterator?
直接写成
for (Map.Entry<String, String> entry : map.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
}
不好吗?
1 楼 Matol 2012-06-26  
打个标记,ok

相关推荐

    map的遍历方法 有几种? 帮你选择最好的遍历方式

    你知道map的遍历方法有几种吗? 那这几种的区别是什么呢? 那种更简单、高效呢? 我的资源文件将告诉你。

    Java中遍历ConcurrentHashMap的四种方式详解

    主要介绍了Java中遍历ConcurrentHashMap的四种方式详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    php array_map array_multisort 高效处理多维数组排序

    3 遍历$arrSort, 根据其索引,获取多维数组的数据,重新构造排序后的多维数组. 复制代码 代码如下:Array ( [0] =&gt; Array ( [link] =&gt; test [name] =&gt; test.rpm [type] =&gt; file [size] =&gt; 988.9k [mtime] =&gt; ...

    双选框 两个<select>标签组成 高效代码清晰

    由两个标签组成的具有挑选功能的js组建。 可实现左侧的元素移到右侧,右侧移到左侧。 有提交功能。 代码简洁、高效复用性强。 本段代码有Map的遍历读者不必细究。

    基于C++解决众数问题(源码+剖析)

    包含了头文件 (用于输入输出操作)、&lt;unordered_map&gt;(用于使用哈希表)和 (用于使用向量)。 在 mode 函数中,我们首先定义了一个 unordered_map, int&gt; 类型的哈希表 freqMap,用于记录每个数出现的频次。 然后,...

    sesvc.exe 阿萨德

    不然就按照链表的方式遍历匹配返回值。 从这两个核心方法(get/put)可以看出 1.8 中对大链表做了优化,修改为红黑树之后查询效率直接提高到了 O(logn)。 但是 HashMap 原有的问题也都存在,比如在并发场景下使用时...

    大数据实验报告.docx

    在生活中,二度好友推荐的运用非常广泛,一般在主流的社交平台上关于好友推荐上就有这方面的应用,当然,在当下海量的数据中,利用MapReduce编程模型来实现不失为一种较好的方式,具体的过程如下图。 这里需要同学...

    Python入门知识经典总结.docx

    使用heapq模块进行高效的最大或最小堆排序,如heapq.nlargest(n, iterable)或heapq.nsmallest(n, iterable)来获取列表中的前n个最大或最小元素。 函数与闭包: 创建闭包以保存外部函数的状态,确保即使外部函数执行...

    GO语言学习文档,适合初级入门学习

    * 特定类型 (映射和通道后面会详细说明) 以引用方式传递, 而非值传递. 传递一个映射给函数不会获得函数的一个拷贝, 所以如果函数改变了其值,调用者能看得到. 在C++中可以理解成引用. *GO没有头文件.取而代之地...

    Java的第六周学习报告

    作者:钟良堂 ...基本集合(动态数组,链表,树,哈希表)的实现也必须是高效的。 该框架允许不同类型的集合,以类似的方式工作,具有高度的互操作性。 对一个集合的扩展和适应必须是简单的。 为此,整个集合框

    分享一下如何编写高效且优雅的 Python 代码

    本文部分提炼自书籍:《Effective Python》&《Python3 Cookbook》,但也做出了修改,并加上了作者自己的理解和运用中的最佳实践。 全文约 9956 字,读完可能需要 24 分钟。...使用列表推导式来取代map和fil

    hibernate总结

    3. QBC ( query by criteria ) 更加面向对象 4. QBE ( query by Example ) 5. SQL Hibernate的检索策略: 1. 延迟检索(加载)映射文件中改变lazy a) Lazy的取值: i. Many-to-one 1. false 2. proxy 3. ...

    Java开发实战1200例(第1卷).(清华出版.李钟尉.陈丹丹).part3

    实例150 实例化Class类的5种方式 196 实例151 获得Class对象表示实体的名称 197 实例152 查看类的声明 198 实例153 查看类的成员 199 实例154 按继承层次对类排序 201 实例155 查看内部类信息 202 7.2 反射的进阶 ...

    JAVA入门1.2.3:一个老鸟的JAVA学习心得 PART1(共3个)

    通过大量的比喻、类比、对比和图示等多种讲解方式,学习效果好 对Java语言的每个语法都提供了一个或多个例程讲解 大量使用流程图表示程序的执行过程,使用结构图表示程序的内部状态 每章最后都给出了典型的练习题,...

    Java入门1·2·3:一个老鸟的Java学习心得.PART3(共3个)

    通过大量的比喻、类比、对比和图示等多种讲解方式,学习效果好 对Java语言的每个语法都提供了一个或多个例程讲解 大量使用流程图表示程序的执行过程,使用结构图表示程序的内部状态 每章最后都给出了典型的练习题,...

Global site tag (gtag.js) - Google Analytics