Java8 HashMap遍历方式性能探讨

作者:Hosee 时间:2022-01-31 08:48:11 

原因:

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

标签:Java8,HashMap,遍历,性能
0
投稿

猜你喜欢

  • Android实现支持所有View的通用的下拉刷新控件

    2022-07-29 10:40:36
  • C#中观察者模式的3种实现方式

    2021-07-03 23:09:42
  • SpringCloud启动失败问题汇总

    2021-07-28 02:45:51
  • 一篇文章带你入门Java之编程规范

    2022-02-25 16:18:40
  • java ArrayList集合中的某个对象属性进行排序的实现代码

    2022-05-27 19:54:24
  • 用Rational Rose逆向工程(java)生成类图(教程和错误解决)

    2023-05-20 20:34:14
  • C#动态创建button的方法

    2023-02-11 15:58:26
  • C#使用Json.Net对JSON与对象的序列化与反序列化

    2023-04-08 07:22:25
  • JavaWeb中的常用的请求传参注解说明

    2023-06-19 03:12:06
  • Android开发中记一个SwipeMenuListView侧滑删除错乱的Bug

    2021-08-02 04:24:21
  • Android 仿苹果IOS6开关按钮

    2023-11-21 15:16:08
  • Hibernate hql查询代码实例

    2021-07-24 18:03:33
  • Android SearchView搜索框组件的使用方法

    2023-06-25 08:13:42
  • mybatis-plus返回查询总记录数方式

    2021-11-27 01:31:34
  • Java设计模式之建造者模式

    2023-09-03 14:40:37
  • Android开发中Toast显示消息的方法小结

    2023-07-31 20:29:14
  • java如何用Processing生成马赛克风格的图像

    2023-11-07 20:52:44
  • Android 高仿微信朋友圈动态支持双击手势放大并滑动查看图片效果

    2021-08-21 21:16:40
  • Android ScrollView滑动实现仿QQ空间标题栏渐变

    2021-06-13 16:32:19
  • java中的枚举类型详细介绍

    2023-06-26 22:31:26
  • asp之家 软件编程 m.aspxhome.com