场景:偶尔生产环境的某台机器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`的方法之一。 **示例代码:** ```java public static void main(String[] args) { Map, String> map = new HashMap(); map.put("1", "value1"); map.put("2", ...
### Java中遍历Map的四种方式及性能比较 在Java编程中,`Map`是一种非常重要的数据结构,用于存储键值对。对于`Map`的遍历,不同的遍历方式有着不同的性能表现以及适用场景。本文将详细介绍四种常见的遍历`Map`的...
你知道map的遍历方法有几种吗? 那这几种的区别是什么呢? 那种更简单、高效呢? 我的资源文件将告诉你。
尽管不推荐,但`keySet()`方法也是可以用来遍历Map的一种方式。首先,`keySet()`返回的是Map中所有键的`Set`集合,然后我们可以通过迭代这个键集,每次迭代获取一个键,再通过`Map.get(key)`获取对应的值。以下是...
### Map集合的四种遍历方式 #### 概述 在Java编程中,`Map`是一种常用的集合类型,用于存储键值对数据。由于其高效的数据查找特性,在实际开发中被广泛应用。本文将详细介绍如何通过四种不同的方法来遍历`Map`集合...
### Java遍历Map对象的所有数据 在Java编程中,`Map`接口是Java集合框架中的一个关键组成部分,它用于存储键值对。本篇文章将详细解释如何遍历`Map`对象的所有数据,并介绍几种常见的遍历方法。我们将重点讨论通过`...
这两种方法都是遍历Map对象的有效方式,选择哪种取决于具体的需求和场景。在处理复杂的数据结构时,Map对象提供了比传统对象更多的灵活性,尤其是在处理大量数据或需要保持插入顺序的情况下。 在实际开发中,了解...
在Java编程语言中,`Map`接口是一种非常重要的数据结构,它存储键值对,并确保每个键都是唯一的。本文将详细介绍Java中Map集合的三种遍历方法及其应用...理解并熟练掌握这些遍历技巧,有助于编写更加高效、优雅的代码。
在Struts2中,我们可以使用OGNL(Object-Graph Navigation Language)表达式语言来遍历Map。 在Struts2中,Map遍历通常在JSP页面上进行,使用OGNL表达式。以下是一个简单的例子: ```jsp ... <s:iterator value="...
3. **遍历Map**:使用`<#list>`指令,我们遍历`dataList`中的每一个Map对象,然后再次使用`<#list>`遍历Map中的每一个键值对。 4. **输出结果**:`${key}`和`${value}`分别代表Map中的键和对应的值,它们会被替换为...
以下是四种遍历 Map 的方法: 1. **使用 for-each 循环遍历 entries** 这是最简单且推荐的遍历方式,适用于需要同时访问键和值的情况。在 Java 5 及以上版本中可用。示例如下: ```java Map, Integer> map = new...
在Java编程语言中,`Map`接口是集合框架的一个重要组成部分,它用于存储键值对。其中,`HashMap`是`Map`接口的一个实现类,...在追求代码可读性和维护性的同时,合理利用这两种遍历策略,可以使程序更加健壮和高效。
在C++编程中,`std::map`和`std::unordered_map`是两种常见的关联容器,它们都用于存储键值对,但实现机制和性能特点有所不同。本篇文章将深入探讨这两种容器在插入、遍历和查找操作上的差异,并通过实例分析它们...
首先,我们来看如何使用`iterator`标签遍历Map。在Java中,Map是一种键值对的数据结构,`iterator`标签可以通过`key`和`value`属性分别获取键和值。例如: ```jsp ... <td><s:property value="key" /> <td><s...
在Java 8中,Map接口引入了新的方法和特性,使得遍历Map变得更为简洁高效。以下是关于Java 8独有的Map遍历方式的详细说明: 1. **通过`Map.keySet()`遍历** 在Java 8之前,遍历Map的传统方式是通过`Map.keySet()`...
以下是Java中遍历Map的几种常见方法,包括使用增强的for循环、迭代器以及通过keySet()和entrySet()方法: 1. **增强的for循环(foreach)** 增强的for循环是Java 5引入的新特性,它可以简洁地遍历集合。对于Map,...
遍历Map有多种方法,每种方法适用于不同的场景。以下将详细介绍标题和描述中提到的几种遍历Map的Java实现方法,并讨论它们的效率问题。 1. **keySet遍历** 使用`keySet()`方法获取Map的所有键,然后通过迭代器或者...
在实际开发中,选择哪种遍历方式取决于具体需求。例如,如果需要按顺序遍历,可能需要先对`Map`进行排序;如果关注性能,可能会选择迭代器方式。了解并熟练掌握这些遍历`Map`的方法,能帮助开发者编写更加高效和灵活...
下面我们将详细介绍如何使用JSTL EL表达式遍历Map集合。 ### JSTL EL表达式概述 JSTL(JavaServer Pages Standard Tag Library)是一个JSP标签库,它简化了JSP页面的开发,使得JSP能够更专注于显示逻辑,而不是...
如果只需要遍历Map的键或值,可以选择这种方式。通过`map.keySet()`获取键集合,或者`map.values()`获取值集合,再进行for-each循环。在性能上,这种方式略优于`entrySet()`,代码也更为简洁。 ```java // 遍历键 ...