你好,游客 登录
背景:
阅读新闻

Java HashMap 遍历方式性能探讨

[日期:2017-08-15] 来源:ImportNew   作者: [字体: ]

  关于HashMap的实现这里就不展开了,具体可以参考 JDK7与JDK8中HashMap的实现

  JDK8之前,可以使用keySet或者entrySet来遍历HashMap,JDK8中引入了map.foreach来进行遍历。

  原因:

  keySet其实是遍历了2次,一次是转为Iterator对象,另一次是从hashMap中取出key所对应的value。而entrySet只是遍历了一次就把key和value都放到了entry中,效率更高。如果是JDK8,使用Map.foreach方法。

  1. keySet和entrySet

  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);

  }

  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);

  }

  源码上看:

  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的过程,这也是两者性能上的主要差别。

  2. 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");

  }

  });

收藏 推荐 打印 | 录入:Cstor | 阅读:
本文评论   查看全部评论 (0)
表情: 表情 姓名: 字数
点评:
       
评论声明
  • 尊重网上道德,遵守中华人民共和国的各项有关法律法规
  • 承担一切因您的行为而直接或间接导致的民事或刑事法律责任
  • 本站管理人员有权保留或删除其管辖留言中的任意内容
  • 本站有权在网站内转载或引用您的评论
  • 参与本评论即表明您已经阅读并接受上述条款