在原始记忆中,Java HashMap遍历,无非是for each或者iterator,但至于在遍历时性能如何,优缺点如何,泛泛而不得知。对于这样的基础问题,对于王二(Java编程6年,幸好我的方向不是编程)我来说,似乎羞于提及,但事实证明,我还必须“积硅步”。

①方法一、iterator迭代keys并搜索values

该种方法是我使用最频繁的,没有之一,详见如下代码:

Map<Integer, Integer> map = new HashMap<Integer, Integer>();addMap(map);long t1 = System.currentTimeMillis();
Iterator<Integer> keys = map.keySet().iterator();while (keys.hasNext()) {Integer key = keys.next();Integer value = map.get(key);keys.remove();
}long t2 = System.currentTimeMillis();
System.out.println(map.keySet().iterator()耗时: + (t2 - t1))

以前的我看来,该种方法使用起来相当简洁,通过iterator遍历出来keys,然后通过key从map中获取对应的value,似乎也非常接地气。但是,弊端就在于

它更慢更低效,通过key得到value值更耗时(这个方法在所有实现map接口的map中比方法#1慢20%-200%)。如果你安装了FindBugs,它将检测并警告你这是一个低效的迭代。这个方法应该避免

看到这条信息,我是觉得有点唐突,怎么原来最喜欢的一种map遍历方式竟然如此low,简直让人失望。后面我会对花费的性能时间做一个统计,稍候关注。

②方法二、Iterator迭代Entry

这种方法我以前几乎不用,但方法二却有其关键的优点:

  1. 可以通过iterator对map的元素进行删除。方法一同样。
  2. 性能优良。
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
addMap(map);
long t3 = System.currentTimeMillis();
Iterator<Entry<Integer, Integer>> entrys = map.entrySet().iterator();while (entrys.hasNext()) {Entry<Integer, Integer> entry = entrys.next();Integer key = entry.getKey();Integer value = entry.getValue();entrys.remove();
}long t4 = System.currentTimeMillis();
System.out.println( map.entrySet().iterator()耗时:" + (t4 - t3));

通过“map.entrySet().iterator()”获得map的entry对象,然后通过getKey,getValue进行key和value值得获取,非常的直白和实用。

③方法三:For-Each迭代keys和values

for each一个局限是不同remove map中的元素,但遍历map还是非常好的。

Map<Integer, Integer> map = new HashMap<Integer, Integer>();
addMap(map);long t5 = System.currentTimeMillis();
for (Integer key : map.keySet()) {
}for (Integer value : map.values()) {
}
long t6 = System.currentTimeMillis();
System.out.println(for each map.keySet()、map.values()耗时:" + (t6 - t5));

不过这里,王二有话要说,按照stackoverflow上所说,该种方法要比接下来说的第四种方法“For-Each迭代entries”性能更好(大约快10%),但在我的实践中并非如此,这种方法反而比第四种“For-Each迭代entries”慢得多。

④方法四:For-Each迭代entries

Map<Integer, Integer> map = new HashMap<Integer, Integer>();
addMap(map);long t7 = System.currentTimeMillis();
for (Entry<Integer, Integer> entry : map.entrySet()) {Integer key = entry.getKey();Integer value = entry.getValue();
}
long t8 = System.currentTimeMillis();
System.out.println(for each map.entrySet()耗时:" + (t8 - t7));

这种方法就不多做介绍了。

⑤性能时间表

次序 iterator迭代keys并搜索values Iterator迭代Entry For-Each迭代keys和values For-Each迭代entries
1 耗时:37 耗时:32 耗时:39 耗时:13
2 耗时:29 耗时:18 耗时:32 耗时:15
3 耗时:50 耗时:57 耗时:39 耗时:21
4 耗时:47 耗时:31 耗时:39 耗时:14

可以总结如下:

  1. 迭代keys并搜索values 非常低效,排名几乎在倒数第一或第二
  2. For-Each迭代entries 性能最佳,但无法remove
  3. For-Each迭代keys和values并没有比For-Each迭代entries 性能(大约快10%),stackoverflow上的数据也不能全部苟同
  4. Iterator迭代Entry 的方案显然最适合使用,性能优良,且可以remove

Java HashMap遍历实践相关推荐

  1. Java HashMap 遍历方式性能探讨

    转载自 Java HashMap 遍历方式性能探讨 关于HashMap的实现这里就不展开了,具体可以参考JDK7与JDK8中HashMap的实现 JDK8之前,可以使用keySet或者entrySet ...

  2. Java HashMap遍历的两种方式

    今天来搞一次HashMap 遍历的操作方式: 经过测试,方式一的效率要远高于方式二.,1000000条测试数据,第一种大概耗时20多秒,第二种耗时大概40多秒.所以,建议以后使用第一种方式. 直接上代 ...

  3. [Java] HashMap遍历的两种方式

    Java中HashMap遍历的两种方式原文地址: http://www.javaweb.cc/language/java/032291.shtml 第一种: Map map = new HashMap ...

  4. java hashmap遍历顺序_Java中HashMap遍历的两种方式

    第一种: Map map =  HashMap(); Iterator iter = map.entrySet().iterator(); (iter.hasNext()) { Map.Entry e ...

  5. java hashmap 遍历 for_Java中HashMap遍历

    在Java中有多种遍历HashMap的方法,注意Java中所有的Map类型都实现了共有的Map接口,所以接下来方法适用于所有Map(如:HaspMap,TreeMap,LinkedMap,HashTa ...

  6. Java HashMap遍历删除

    map的迭代删除,和我们常见的list,set不太一样,不能直接获取Iteraotr对象,提供的删除方法也是单个的,根据key进行删除,如果我们有个需求,将map中满足某些条件的元素删除掉,要怎么做呢 ...

  7. Java中HashMap遍历的两种方式

    第一种: Map map = new HashMap(); Iterator iter = map.entrySet().iterator(); while (iter.hasNext()) { Ma ...

  8. Java 集合List、Set、HashMap操作一(Array转List、Set排序、HashMap遍历、Set遍历、List遍历、HashMap大小长度、List打乱顺序)

    数组转集合(Array转List) import java.util.*; import java.io.*;public class ArrayToCollection{public static ...

  9. Java 基础——HashMap 遍历方式

    目录 1.使用迭代器 (Iterator) EntrySet 的方式进行遍历 2.使用迭代器 (Iterator) KeySet 的方式进行遍历 3.使用 foreach EntrySet 的方式进行 ...

最新文章

  1. 无语!你竟然连CompletableFuture都不知道,还天天说在jdk8原地踏步~
  2. linux编译配置过程,make menuconfig/.config/Kconfig的关系
  3. iOS6.0 xcode4.5 设置横屏
  4. Oracle中查看所有表和字段
  5. 多项目Node版本控制
  6. 解决Linux新创建的文件夹带锁问题
  7. azure云数据库_如何使用SQL Data Sync同步Azure SQL数据库和本地数据库
  8. 以太坊智能合约开发,Web3.js API 中文文档 ethereum web3.js入门说明
  9. vue-router 中router-view不能渲染
  10. android定时截取屏幕内容,Android 截取手机屏幕两种实现方案解析
  11. python图像标记工具怎么用_图像标注教程(使用LabelImg标注工具)
  12. 9.5.3 Android Apk 反编译 9.5.4 Android Apk 加密
  13. mysql实现不同电脑间局域网连接
  14. MHZ是计算机的什么单位,电脑mhz是什么意思
  15. eu指什么_鞋码eu是什么意思 鞋子尺码eu对照表
  16. 四城市十行业紧缺人才信息公布
  17. 为什么外包公司这么不受欢迎??
  18. 编解码学习笔记(三) Mpeg系列——Mpeg 1和Mpeg 2
  19. 阿里云-云开发平台计算篇——加强应用本身的计算能力
  20. nplayer,es文件浏览器等进行局域网连接时登录不上或者不断弹出登录框的问题

热门文章

  1. MATLAB cumsum函数用法
  2. 用ftp的网址无法在谷歌浏览器打开:用ie浏览器打开
  3. hnust 好友互动标识
  4. 如何录制视频?快速录制视频方法介绍:
  5. 【OBS编译】基于VS2019的W10下的编译
  6. PS怎样把选区保存起来?(用通道的方式)
  7. android 9.0定时开机的实现
  8. c++中也有java中的匿名内部类
  9. 关于自建网站那些事情
  10. 《逐梦旅程 WINDOWS游戏编程之从零开始》笔记10——三维天空的构建三维粒子的实现多游戏模型的载入...