Java8 HashMap遍历方式性能探讨
作者:Hosee 发布时间:2022-01-31 08:48:11
标签:Java8,HashMap,遍历,性能
原因:
keySet其实是遍历了2次,一次是转为Iterator对象,另一次是从hashMap中取出key所对应的value。而entrySet只是遍历了一次就把key和value都放到了entry中,效率更高。如果是JDK8,使用Map.foreach方法。
一. keySet和entrySet
Map<String, String> map = new HashMap<String, String>();
int num = 5000000;
String key, value;
// 存放500万条数据
for (int i = 1; i <= num; i++) {
key = "" + i;
value = "value";
map.put(key, value);
}
1.1 基本用法
keySet:
Map map=new HashMap();
Iterator it=map.keySet().iterator();
Object key;
Object value;
while(it.hasNext()){
key=it.next();
value=map.get(key);
System.out.println(key+":"+value);
}
时间:只获取key 50;获取key和value 170
entrySet:
Map map=new HashMap();
Iterator it=map.entrySet().iterator();
Object key;
Object value;
while(it.hasNext()){
Map.Entry entry = (Map.Entry)it.next();
key=entry.getKey();
value=entry.getValue();
System.out.println(key+"="+value);
}
时间:只获取key或获取value 时间差不多 110-140;获取key和value 140
源码上看:
keySet:
final class KeyIterator extends HashIterator
implements Iterator<K> {
public final K next() { return nextNode().key; }
}
entrySet:
final class EntryIterator extends HashIterator
implements Iterator<Map.Entry<K,V>> {
public final Map.Entry<K,V> next() { return nextNode(); }
}
其实这里已经很明显了,当要得到某个value时,keySet还需要从HashMap中get,entrySet相比keySet少了遍历table的过程,这也是两者性能上的主要差别。
for (String key1 : map.keySet()) {
value = map.get(key1);
}
时间:170
for (Entry<String, String> entry1 : map.entrySet()) {
key = entry1.getKey();
value = entry1.getValue();
}
时间:130
比较:keySet其实是遍历了2次,一次是转为Iterator对象,另一次是从hashMap中取出key所对应的value。而entrySet只是遍历了一次就把key和value都放到了entry中,效率更高。如果是JDK8,使用Map.foreach方法。
二. Map.foreach
在JDK8以后,引入了Map.foreach。
Map.foreach本质仍然是entrySet
default void forEach(BiConsumer<? super K, ? super V> action) {
Objects.requireNonNull(action);
for (Map.Entry<K, V> entry : entrySet()) {
K k;
V v;
try {
k = entry.getKey();
v = entry.getValue();
} catch(IllegalStateException ise) {
// this usually means the entry is no longer in the map.
throw new ConcurrentModificationException(ise);
}
action.accept(k, v);
}
}
配合lambda表达式一起使用,操作起来更加方便。
2.1 使用Java8的foreach+lambda表达式遍历Map
Map<String, Integer> items = new HashMap<>();
items.put("A", 10);
items.put("B", 20);
items.put("C", 30);
items.put("D", 40);
items.put("E", 50);
items.put("F", 60);
items.forEach((k,v)->System.out.println("Item : " + k + " Count : " + v));
items.forEach((k,v)->{
System.out.println("Item : " + k + " Count : " + v);
if("E".equals(k)){
System.out.println("Hello E");
}
});
时间:158
来源:https://my.oschina.net/hosee/blog/1488876


猜你喜欢
- c#中通过反射可以方便的动态加载dll程序集,但是如果你需要对dll进行更新,却发现.net类库没有提供卸载dll程序集的方法。在.net
- 第一种方法:string s=abcdeabcdeabcde;string[] sArray=s.Split(c) ;foreach(str
- 本文实例为大家分享了java实现拼图游戏的具体代码,供大家参考,具体内容如下游戏说明:设计一款拼图游戏,要求点击图片按钮,实现图片按钮的移动
- 官方文档:https://central.sonatype.org/publish/publish-maven/#a-complete-ex
- 网上看了很多篇文章关于如何配置mybatis的logback日志的,复杂的简单的都有,但是有用的没几个,耽误了很多时间。通过对logback
- 一.添加控件IrisSkin2.dll。方法:  
- 单例模式应该是设计模式中比较简单的一个,也是非常常见的,但是在多线程并发的环境下使用却是不那么简单了,今天给大家分享一个我在开发过程中遇到的
- 背景公司的一个服务需要做类似于分片的逻辑,一开始服务基于传统部署方式通过本地配置文件配置的方式就可以指定该机器服务的分片内容如:0,1,2,
- 太多的if-else不太直观,难以维护。 以下面代码为例,展示几种替代if else的方法。String input = &quo
- 首先介绍一些乐观锁与悲观锁:悲观锁:总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个
- 继承JpaRepository,找不到findOne()方法问题:以前一直使用findOne(ID id);,这次用SpringBoot构建
- import java.io.File;import java.io.FileNotFoundException;import java.i
- 前言又没什么好的思路,还是随便写一些,所以这次就来整点活。我们都知道Activity的跳转拥有默认的跳转动画,或者把这个默认的动画给取消,就
- 先看看效果图:实现思路:监听ListView的滑动,等目的项为列表第一个可见的ItemView时,添加一个一个的布局,产生悬停效果实现代码:
- 本文介绍了Android ItemDecoration 实现分组索引列表的示例代码,分享给大家。具体如下:先来看看效果:我们要实现的效果主要
- 前言:最近突然喜欢上一句诗:“宠辱不惊,看庭前花开花落;去留无意,望天空云卷云舒。” 哈哈~,这个和今天的主题无关,最近只要不学习总觉得生活
- 网上查找资料要么是细节不够失败要么是根本没用也不需要这么复杂,在这里总结一下本人在宝塔部署前端和后端的方法。1.在宝塔上添加站点&u
- 前言在我们公司里,不同的服务之间通过Feign进行远程调用,但是,我们在尝试使调用可重试时遇到了一个小问题,Feign框架本身可以配置的自己
- const和readonly经常被用来修饰类的字段,两者有何异同呢?const1、声明const类型变量一定要赋初值吗?一定要赋初值publ
- JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,是理想的数据交换