`

Map的高效遍历

    博客分类:
  • J2EE
阅读更多
引用
场景:偶尔生产环境的某台机器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();     
}
   





分享到:
评论

相关推荐

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

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

    map遍历的四种方法

    - **适用场景:**适用于需要高效遍历键值对的场景。 #### 三、通过`Map.entrySet()`和增强型for循环遍历键和值 这种方法同样利用了`entrySet`视图,但是使用的是增强型for循环而非迭代器。这种方式更加简洁明了,...

    C++11 unordered_map与map(插入,遍历,Find)效率对比。

    - `std::unordered_map`:遍历哈希表通常需要遍历所有桶,因此其时间复杂度也是O(n),但实际运行速度可能比`std::map`快,尤其是当元素数量很大时。 **查找操作**: - `std::map`:查找操作同样为O(log n),因为...

    java集合MAP三种遍历

    在Java编程语言中,`Map`接口是一种非常重要的数据结构,它存储键值对,并确保每个键都是唯一的。本文将详细介绍Java中Map集合的三种遍历方法及其应用...理解并熟练掌握这些遍历技巧,有助于编写更加高效、优雅的代码。

    java中Map的两种遍历方法

    在处理数据时,我们经常需要遍历`Map`中的元素。本文将详细探讨在Java中遍历`Map`的两种常用方法:通过`keySet()`方法和通过`entrySet()`方法。 ### 一、通过`keySet()`方法遍历`Map` #### 方法概述 `keySet()`...

    JAVA遍历Map所有元素.doc

    遍历Map的所有元素是常见的操作,特别是在处理数据或者进行调试时。本文将详细讲解两种主要的遍历Map元素的方法,并分析它们的效率差异。 ### 方法一:通过`entrySet()`遍历 这是推荐的遍历Map元素的方式,因为它...

    js遍历map javaScript遍历map的简单实现

    Map对象提供了一种高效的方式来管理和遍历这些键值对。在JavaScript中,遍历Map对象通常有两种主要的方法:使用`for...of`循环和使用`Map.prototype.forEach()`方法。 首先,让我们来看看在给定的描述中展示的简单...

    map遍历的四种方式及性能比较

    ### Java中遍历Map的四种方式及性能比较 在Java编程中,`Map`是一种非常重要的数据结构,用于存储键值对。...通过了解这些遍历方式的优缺点及适用场景,可以帮助开发者编写出更高效、更易于维护的代码。

    struts2中的map遍历

    在Struts2中,Map遍历是一个常见的功能,它允许开发者动态地展示或操作存储在Map中的数据。这个功能在处理表单提交、传递参数或者在视图层展示数据时尤为有用。 首先,让我们理解Map遍历的基本概念。Map是一种键值...

    Map遍历方法总结

    ### Map遍历方法总结 #### 一、引言 在Java编程中,`Map`是一种常用的集合类型,用于存储键值对数据。由于其高效的数据查找特性,在许多场景下都有广泛的应用。对于开发者来说,了解如何有效地遍历`Map`中的元素是...

    JAVA8独有的map遍历方式(非常好用)

    在Java 8中,Map接口引入了新的方法和特性,使得遍历Map变得更为简洁高效。以下是关于Java 8独有的Map遍历方式的详细说明: 1. **通过`Map.keySet()`遍历** 在Java 8之前,遍历Map的传统方式是通过`Map.keySet()`...

    Map集合的四种遍历方式 .txt

    一般来说,第三种方法(通过增强型`for`循环遍历`Map.entrySet()`)是最为简洁和高效的,因为它能够直接访问键值对,避免了额外的`get`操作。而在只需要遍历值的情况下,则可以考虑第四种方法。掌握这些遍历技巧对于...

    Java Map 遍历比较齐全的解析.docx

    总结,Java中遍历`Map`主要有四种方式,其中通过`Map.entrySet()`进行遍历通常被认为效率较高,尤其在`Map`容量较大的情况下。而在Java 8之后,我们可以利用Lambda表达式简化遍历操作。获取`Map`的长度直接调用`size...

    Java实现Map集合遍历的四种常见方式与用法分析

    这种方式比第一种方式更加高效,因为我们可以在遍历过程中同时获取键和值。 第三种方式:通过Iterator遍历获取键和值 在第三种方式中,我们可以使用Iterator对象来遍历Map集合中的键和值。示例代码如下: ```java ...

    FreeMarker 遍历list

    3. **遍历Map**:使用`&lt;#list&gt;`指令,我们遍历`dataList`中的每一个Map对象,然后再次使用`&lt;#list&gt;`遍历Map中的每一个键值对。 4. **输出结果**:`${key}`和`${value}`分别代表Map中的键和对应的值,它们会被替换为...

    Map遍历方法

    ### Map遍历方法详解 #### 一、引言 在Java编程中,`Map`是一种常用的集合类型,用于存储键值对数据。由于其高效的数据查找特性,在许多场景下都有广泛的应用。对于开发者来说,掌握如何有效地遍历`Map`中的元素是...

    Java Map遍历方式的选择

    Java Map的遍历方式在实际应用中是一个重要的性能优化考虑因素。常见的遍历方式有三种:keySet、entrySet和values。很多开发者推荐使用entrySet,认为它比keySet更高效,因为entrySet能一次性获取键值对,避免了额外...

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

    这种方式的优点是可以安全地遍历Map的内容,并且可以在遍历过程中修改Map的内容。但是,需要注意的是,使用Iterator遍历需要手动地迭代每个元素,这可能会导致遍历速度相对较慢。 方式四:通过键找值遍历 这种方式...

    浅谈c++ vector和map的遍历和删除对象

    遍历`map`同样使用迭代器: ```cpp map, int&gt; mapTest; // 添加元素到mapTest map, int&gt;::iterator mapIter; for (mapIter = mapTest.begin(); mapIter != mapTest.end(); ++mapIter) { std::cout &lt;&lt; mapIter-&gt;...

Global site tag (gtag.js) - Google Analytics