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


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

代码中采用了如下的遍历

Java代码  

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

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

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

Java代码  

  1. public V get(Object key) {
  2. if (key == null)
  3. return getForNullKey();
  4. int hash = hash(key.hashCode());
  5. for (Entry<K,V> e = table[indexFor(hash, table.length)];
  6. e != null;
  7. e = e.next) {
  8. Object k;
  9. if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
  10. return e.value;
  11. }
  12. return null;
  13. }

正确用法如下:

Java代码  

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

对比测试

Java代码  

  1. public class HashMapTest {
  2. public static void getFromMap(Map map){
  3. for(Iterator ite = map.keySet().iterator(); ite.hasNext();){
  4. Object key = ite.next();
  5. Object value = map.get(key);
  6. }
  7. }
  8. public static void getFromMapByEntrySet(Map map){
  9. for(Iterator ite = map.entrySet().iterator(); ite.hasNext();){
  10. Map.Entry entry = (Map.Entry) ite.next();
  11. entry.getKey();
  12. entry.getValue();
  13. }
  14. }
  15. public static void main(String[] args) {
  16. Map map = new HashMap();
  17. for(int i=0;i<200000;i++){
  18. map.put("key"+i, "value"+i);
  19. }
  20. long currentTime = System.currentTimeMillis();
  21. getFromMap(map);
  22. long currentTime2 = System.currentTimeMillis();
  23. getFromMapByEntrySet(map);
  24. long currentTime3 = System.currentTimeMillis();
  25. System.out.println(currentTime2-currentTime);
  26. System.out.println(currentTime3-currentTime2);
  27. }
  28. }

运行结果:

Java代码  

  1. 16
  2. 0

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

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

Java代码  

  1. for(Iterator i = map.values().iterator(); i.hasNext();)   {
  2. Object temp =  i.next();
  3. }
时间: 2024-10-17 02:10:24

遍历map 哪种方式更加高效。的相关文章

map遍历的四种方式

原文 http://blog.csdn.net/dayanxuqun/article/details/26348277 以下是map遍历的四种方式: [java] view plaincopyprint? // 一.推荐只用value的时候用,都懂的... // Map.values()遍历所有的value,不遍历key for (String v : map.values()) { System.out.println("value= " + v); } [java] view pl

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

转自:HashMap遍历的两种方式,推荐使用entrySet() 第一种: Map map = new HashMap(); Iterator iter = map.entrySet().iterator(); while (iter.hasNext()) {     Map.Entry entry = (Map.Entry) iter.next();     Object key = entry.getKey();     Object val = entry.getValue(); } 效率

Java Enum枚举 遍历判断 四种方式(包括 Lambda 表达式过滤)

package com.miracle.luna.lambda; import java.util.Arrays; /** * @Author Miracle Luna * @Date 2019/6/9 23:40 * @Version 1.0 */ public enum AlarmGrade { ATTENTION("attention", "提示"), WARNING("warning","警告"), SERIOUS(&

数组遍历的2种方式

for o in aa{ println(o) } for (index,value) in enumerate(aa){ println("\(index)\(value)") } 数组遍历的2种方式,布布扣,bubuko.com

集合遍历的几种方式

集合遍历有几种方式,下面是我总结的. 1     增强for循环:foreach       语法: for(类型 变量:集合名){  } 这是上名代码的结果 集合: 非单个数据的存储:     Iterator it = 集合对象.iterator();     调用对象自己的iterator() 创建属于这个对象自己的迭代器,然后把迭代器赋值给迭代器的父类     多态:迭代器进行向上转型     就是父类的引用指向子类的对象         向上转型 向下转型       Iterator

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

C++ 数组遍历的两种方式: #include <iostream> using namespace std; int main() { // 一维数组 int fibonacci[5] = {1, 1, 2, 3, 5}; // 使用索引遍历 // 求数组长度:sizeof(array)/sizeof(array[0]) cout << "Traverse By Index: "; for (int i = 0; i < sizeof(fibonacci

Map集合遍历的四种方式理解和简单使用-----不能for循环遍历

~Map集合是键值对形式存储值的,所以遍历Map集合无非就是获取键和值,根据实际需求,进行获取键和值 1:无非就是通过map.keySet()获取到值,然后根据键获取到值 for(String s:map.keySet()){            System.out.println("key : "+s+" value : "+map.get(s));     } 2:通过Map.Entry(String,String) 获取,然后使用entry.getKey(

Java中HashMap遍历的两种方式

第一种: Map map = new HashMap(); Iterator iter = map.entrySet().iterator(); while (iter.hasNext()) { Map.Entry entry = (Map.Entry) iter.next(); Object key = entry.getKey(); Object val = entry.getValue(); } 效率高,以后一定要使用此种方式! 第二种: Map map = new HashMap();

java集合遍历的几种方式总结及比较

集合类的通用遍历方式, 用迭代器迭代: Iterator it = list.iterator(); while(it.hasNext()) { Object obj = it.next(); } Map遍历方式: 1.通过获取所有的key按照key来遍历 //Set<Integer> set = map.keySet(); //得到所有key的集合 for (Integer in : map.keySet()) { String str = map.get(in);//得到每个key多对用v