Java HashMap三种循环遍历方式及其性能对比实例分析

作者:xuexuan_050848 时间:2022-03-22 18:36:45 

本文实例讲述了Java HashMap三种循环遍历方式及其性能对比。分享给大家供大家参考,具体如下:

HashMap的三种遍历方式

(1)for each map.entrySet()


Map<String, String> map = new HashMap<String, String>();
for (Entry<String, String> entry : map.entrySet()) {
 entry.getKey();
 entry.getValue();
}

(2)显示调用map.entrySet()的集合迭代器


Iterator<Map.Entry<String, String>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
 entry.getKey();
 entry.getValue();
}

(3)for each map.keySet(),再调用get获取


Map<String, String> map = new HashMap<String, String>();
for (String key : map.keySet()) {
 map.get(key);
}

三种遍历方式的性能测试及对比

测试环境:Windows7 32位系统 3.2G双核CPU 4G内存,Java 7,Eclipse -Xms512m -Xmx512m

测试结果:

map size10,000100,0001,000,0002,000,000
for each entrySet2ms6ms36ms91ms
for iterator entrySet0ms4ms35ms89ms
for each keySet1ms6ms48ms126ms

遍历方式结果分析

由上表可知:

  • for each entrySet与for iterator entrySet性能等价

  • for each keySet由于要再调用get(key)获取值,比较耗时(若hash散列算法较差,会更加耗时)

  • 在循环过程中若要对map进行删除操作,只能用for iterator entrySet(在HahsMap非线程安全里介绍)。

HashMap entrySet源码


private final class EntryIterator extends HashIterator<Map.Entry<K,V>> {
 public Map.Entry<K,V> next() {
   return nextEntry();
 }
}

HashMap keySet源码


private final class KeyIterator extends HashIterator<K> {
 public K next() {
   return nextEntry().getKey();
 }
}

由源码可知:

keySet()与entrySet()都是返回set的迭代器。父类相同,只是返回值不同,因此性能差不多。只是keySet()多了一步根据key get value的操作而已。get的时间复杂度取决于for循环的次数,即hash算法。


public V get(Object key) {
 if (key == null)
   return getForNullKey();
 Entry<K,V> entry = getEntry(key);
 return null == entry ? null : entry.getValue();
}
/**
1. Returns the entry associated with the specified key in the
2. HashMap. Returns null if the HashMap contains no mapping
3. for the key.
*/
final Entry<K,V> getEntry(Object key) {
 int hash = (key == null) ? 0 : hash(key);
 for (Entry<K,V> e = table[indexFor(hash, table.length)];
    e != null;
    e = e.next) {
   Object k;
   if (e.hash == hash &&
     ((k = e.key) == key || (key != null && key.equals(k))))
     return e;
 }
 return null;
}

结论

  • 循环中需要key、value,但不对map进行删除操作,使用for each entrySet

  • 循环中需要key、value,且要对map进行删除操作,使用for iterator entrySet

  • 循环中只需要key,使用for each keySet

更多java相关内容感兴趣的读者可查看本站专题:《Java数据结构与算法教程》、《Java操作DOM节点技巧总结》、《Java文件与目录操作技巧汇总》和《Java缓存操作技巧汇总》

希望本文所述对大家java程序设计有所帮助。

来源:https://blog.csdn.net/xuexuan_050848/article/details/52004685

标签:Java,HashMap,循环遍历
0
投稿

猜你喜欢

  • 在web.config和app.config文件中增加自定义配置节点的方法

    2021-11-03 03:21:41
  • 解决maven没有打包xml文件的问题

    2023-11-27 14:51:01
  • Android自定义View模仿即刻点赞数字切换效果实例

    2023-08-26 12:45:39
  • Spring Boot实现STOMP协议的WebSocket的方法步骤

    2022-10-01 07:12:27
  • 解读在C#中winform程序响应键盘事件的详解

    2023-10-08 09:17:00
  • Android自定义View仿IOS圆盘时间选择器

    2023-10-12 20:40:32
  • SpringBoot实现单文件上传

    2023-10-01 21:43:42
  • android 线性布局LinearLayout实例代码

    2023-02-23 19:30:13
  • Java算法实现调整数组顺序使奇数位于偶数之前的讲解

    2022-01-23 22:41:19
  • Android Vitamio和ExoPlayer两种播放器优劣分析

    2023-02-25 13:21:51
  • Android编程实现图片的颜色处理功能示例

    2022-10-08 23:15:25
  • mybatis 通过拦截器打印完整的sql语句以及执行结果操作

    2023-07-06 04:26:42
  • springcloud使用feign调用服务时参数内容过大问题

    2022-08-31 11:23:26
  • 详解spring mvc中url-pattern的写法

    2023-11-11 07:30:58
  • Java实现动态模拟时钟

    2022-07-25 17:35:25
  • C#中foreach语句使用break暂停遍历的方法

    2022-10-12 20:14:11
  • android解析JSON数据

    2022-10-17 04:55:40
  • opencv3/C++ FLANN特征匹配方式

    2021-08-19 10:17:47
  • 自定义BufferedReader的实例

    2021-06-10 08:13:39
  • Android实现底部滚轮式选择弹跳框

    2022-02-05 15:13:09
  • asp之家 软件编程 m.aspxhome.com