Java HashMap遍历实践,看看不同方式的性能如何
2016-03-04 13:23
537 查看
在原始记忆中,Java HashMap遍历,无非是for each或者iterator,但至于在遍历时性能如何,优缺点如何,泛泛而不得知。对于这样的基础问题,对于王二(Java编程6年,幸好我的方向不是编程)我来说,似乎羞于提及,但事实证明,我还必须“积硅步”。
以前的我看来,该种方法使用起来相当简洁,通过iterator遍历出来keys,然后通过key从map中获取对应的value,似乎也非常接地气。但是,弊端就在于
它更慢更低效,通过key得到value值更耗时(这个方法在所有实现map接口的map中比方法#1慢20%-200%)。如果你安装了FindBugs,它将检测并警告你这是一个低效的迭代。这个方法应该避免
看到这条信息,我是觉得有点唐突,怎么原来最喜欢的一种map遍历方式竟然如此low,简直让人失望。后面我会对花费的性能时间做一个统计,稍候关注。
可以通过iterator对map的元素进行删除。方法一同样。
性能优良。
通过“map.entrySet().iterator()”获得map的entry对象,然后通过getKey,getValue进行key和value值得获取,非常的直白和实用。
不过这里,王二有话要说,按照stackoverflow上所说,该种方法要比接下来说的第四种方法“For-Each迭代entries”性能更好(大约快10%),但在我的实践中并非如此,这种方法反而比第四种“For-Each迭代entries”慢得多。
这种方法就不多做介绍了。
可以总结如下:
迭代keys并搜索values 非常低效,排名几乎在倒数第一或第二
For-Each迭代entries 性能最佳,但无法remove
For-Each迭代keys和values并没有比For-Each迭代entries 性能(大约快10%),stackoverflow上的数据也不能全部苟同
Iterator迭代Entry 的方案显然最适合使用,性能优良,且可以remove
①方法一、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
这种方法我以前几乎不用,但方法二却有其关键的优点:可以通过iterator对map的元素进行删除。方法一同样。
性能优良。
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 |
迭代keys并搜索values 非常低效,排名几乎在倒数第一或第二
For-Each迭代entries 性能最佳,但无法remove
For-Each迭代keys和values并没有比For-Each迭代entries 性能(大约快10%),stackoverflow上的数据也不能全部苟同
Iterator迭代Entry 的方案显然最适合使用,性能优良,且可以remove
参考文章
HashMap遍历相关文章推荐
- Java HashMap遍历实践
- JAVA_常用工具类
- 【SpringMVC】SpringMVC系列6之@CookieValue 映射请求Cookie 值
- spring编码过滤器 配置
- Java 异常类型
- 【SpringMVC】SpringMVC系列5之@RequestHeader 映射请求头属性值
- java中断文章
- java学习笔记-输入输出流
- 【SpringMVC】SpringMVC系列4之@RequestParam 映射请求参数值
- Android Studio 导入 Eclipse 项目
- 【SpringMVC】SpringMVC系列3之@PathVariable映射URL占位符参数
- angular与SpringMVC项目 跨域请求
- SpringMVC+easyUI CRUD 添加数据C
- 【转载】java版打字练习软件
- Eclipse包文件里面的全部替换
- eclipse找不到jdk来运行
- Java--容器(Collection)(二)
- 《Spring in action》3rd中SpringPizza项目的运行方法
- java.security.AccessControlException: access denied
- java.rmi.ConnectException: Connection refused to host: