引用
场景:偶尔生产环境的某台机器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中遍历ConcurrentHashMap的四种方式详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
由两个标签组成的具有挑选功能的js组建。 可实现左侧的元素移到右侧,右侧移到左侧。 有提交功能。 代码简洁、高效复用性强。 本段代码有Map的遍历读者不必细究。
3 遍历$arrSort, 根据其索引,获取多维数组的数据,重新构造排序后的多维数组. 复制代码 代码如下:Array ( [0] => Array ( [link] => test [name] => test.rpm [type] => file [size] => 988.9k [mtime] => ...
包含了头文件 (用于输入输出操作)、<unordered_map>(用于使用哈希表)和 (用于使用向量)。 在 mode 函数中,我们首先定义了一个 unordered_map, int>...通过使用哈希表记录每个数的频次,我们可以高效地找出众数。
使用heapq模块进行高效的最大或最小堆排序,如heapq.nlargest(n, iterable)或heapq.nsmallest(n, iterable)来获取列表中的前n个最大或最小元素。 函数与闭包: 创建闭包以保存外部函数的状态,确保即使外部函数执行...
如果在遍历过程中找到 key 相同时直接退出遍历。 如果 e != null 就相当于存在相同的 key,那就需要将值覆盖。 最后判断是否需要进行扩容。 get 方法 public V get(Object key) { Node,V> e; return (e = getNode...
* GO提供哈希表,称之类映射(map) * 分离的线程执行, 通过通道通讯,也是语言本身集成的.后面会详细讨论. * 特定类型 (映射和通道后面会详细说明) 以引用方式传递, 而非值传递. 传递一个映射给函数不会获得...
在传统的关系型数据库中,可以通过图的广度优先遍历算法实现,而且深度限定为2,然而在海量的数据中,这样的遍历成本太大,所以有必要利用MapReduce编程模型来并行化。本次实验就是通过MapReduce的思想来实现二度...
本文部分提炼自书籍:《Effective Python》&《Python3 Cookbook》,但也做出了修改,并加上了作者自己的理解和运用中的最佳实践。 全文约 9956 字,读完可能需要 24 分钟。...使用列表推导式来取代map和fil
作者:钟良堂 ...基本集合(动态数组,链表,树,哈希表)的实现也必须是高效的。 该框架允许不同类型的集合,以类似的方式工作,具有高度的互操作性。 对一个集合的扩展和适应必须是简单的。 为此,整个集合框
实例059 Map映射集合实现省市级联选择框 73 第4章 字符串处理技术 75 4.1 格式化字符串 76 实例060 把数字格式化为货币字符串 76 实例061 格式化当前日期 77 实例062 货币金额大写格式 78 实例063 String类格式化...
3. extra 根据对set容器的不同,可以产生高效的sql访问数据库 2. 批量检索:batch-size=3 a) 可以使用批量检索: b) 在内存中,如果有多个set(代理)容器需要初始化, 则当访问任何一个代理set容器时,一次初始化...
配16小时多媒体教学视频,高效、直观 一一击破Java入门可能会遇到的难点和疑惑 抽丝剥茧,层层推进,让知识环环相扣,降低了学习的难度 通过大量的比喻、类比、对比和图示等多种讲解方式,学习效果好 对Java语言的...
配16小时多媒体教学视频,高效、直观 一一击破Java入门可能会遇到的难点和疑惑 抽丝剥茧,层层推进,让知识环环相扣,降低了学习的难度 通过大量的比喻、类比、对比和图示等多种讲解方式,学习效果好 对Java语言的...