HashMap 遍历的两种方式及性能比较
HashMap 是Java开发中经常使用的数据结构。相信HashMap 的基本用法你已经很熟悉了。那么我们该如何遍历HashMap 呢?哪种遍历方式的性能更好呢?本篇文章来为你解决这个疑惑。
一、HashMap 遍历
如果你了解一些HashMap 底层原理,那么你肯定知道HashMap 是一个存储键值对的集合,每个键值对叫Entry。Entry 组成的数组构成了整个HashMap 的主干。Entry 的索引是通过Hash()方法计算出来的。因此Entry在数组内部是无序的(所以我们不能单纯的用for语句有序遍历)。那么我们该如何遍历HashMap 呢?
1. 使用EntrySet遍历
HashMap 的内部有一个EntrySet方法可以让我们方便地获取HashMap 数组内的所有Entry。假设我们有一个这样的HashMap。
HashMap<String,Integer> map=new HashMap<String,Integer>();
我们可以这样获取EntrySet。
Set<Entry<String, Integer>> entrySet=map.entrySet();
这样就得到了HashMap 中所有的Entry。获取Entry 之后遍历就简单多了。我们可以用foreach 语句遍历
Set<Entry<String, Integer>> entrySet=map.entrySet();
for (Entry<String, String> entry : entrySet) {
System.out.println(entry.getKey()+":"+entry.getValue());
}
或者使用迭代器的方式:
Iterator<Map.Entry<String, String>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, String> entry = iterator.next();
System.out.println(entry.getKey()+":"+entry.getValue());
}
2.使用KeySet 遍历
HashMap 中的KeySet方法可以将把Map中所有的键存入到set集合中。再根据get方法,就可以获取到每一个键对应的值。 使用KeySet 遍历的代码如下:
for (String key : map.keySet()) {
System.out.println(key+":"+map.get(key));
}
补充一点,如果你想获取Hashmap 中所有的value,你可以用values 方法。该方法返回一个包含所有value 的collection。
Collection<String> collection = map.values();
System.out.println(collection);
二、性能比较
网上对这两种遍历方法进行性能比较的文章有很多,我在此就不详细比较了。结论就是,使用EntrySet (也就是第一种方式)进行遍历的性能更好,无论你是使用foreach还是迭代器,只要你用的是EntrySet 的方式就可以。而KeySet的方式性能就很差,至于KeySet为什么性能很差,我们可以看看遍历KeySet 时用到的get() 方法的源码(JDK 1.6 ver)。
public V get(Object key) {
if (key == null)
return getForNullKey();
int hash = hash(key.hashCode());
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.equals(k)))
return e.value;
}
return null;
}
可以看出来,源码先获取了key 对应的hash值 ,然后根据hash值在HashMap 的Entry 数组内遍历出hash值与key的hash值相等的Entry,并返回对应的Value。所以get() 方法在获取Value 的时候又进行了一次循环,这导致了性能的下降。
三、总结
总结一下,我们介绍了两种遍历HashMap 的方法,一种是用EntrySet,另一种是用KeySet。性能上EntrySet 优于KeySet ,这是因为KeySet 的get方法在获取Value 的时候需要进行遍历。所以推荐遍历HashMap 的时候使用EntrySet 的方法。
HashMap 遍历的两种方式及性能比较的更多相关文章
- Java中HashMap遍历的两种方式
Java中HashMap遍历的两种方式 转]Java中HashMap遍历的两种方式原文地址: http://www.javaweb.cc/language/java/032291.shtml 第一种: ...
- [Java] HashMap遍历的两种方式
Java中HashMap遍历的两种方式原文地址: http://www.javaweb.cc/language/java/032291.shtml第一种: Map map = new HashMap( ...
- HashMap遍历的两种方式
第一种: Map map = new HashMap(); Iterator iter = map.entrySet().iterator(); while (iter.hasNext()) { ...
- HashMap遍历的两种方式,推荐使用entrySet()
第一种: Map map = new HashMap(); Iterator iter = map.entrySet().iterator(); while (iter.hasNext()) { ...
- python中字典的循环遍历的两种方式
开发中经常会用到对于字典.列表等数据的循环遍历,但是python中对于字典的遍历对于很多初学者来讲非常陌生,今天就来讲一下python中字典的循环遍历的两种方式. 注意: python2和python ...
- C++ 数组遍历的两种方式
C++ 数组遍历的两种方式: #include <iostream> using namespace std; int main() { // 一维数组 ] = {, , , , }; / ...
- Java中HashMap遍历的两种方法(转)
第一种: Map map = new HashMap(); Iterator iter = map.entrySet().iterator(); while (iter.hasNext()) { Ma ...
- php对数组遍历的两种方式示例
在对 php 数组遍历时,一般经常使用 foreach 来遍历,很少用 while 来遍历,在下面的代码中作一个对比. <?php $content = ["ID" => ...
- 【React】遍历的两种方式
1.foreach(推荐) list.forEach((item)=>{ }); eg: dataSource.forEach((item) => { const est = item.e ...
随机推荐
- poj_2112 网络最大流+二分法
题目大意 有K台挤奶机和C头奶牛,都被视为物体,这K+C个物体之间存在路径.给出一个 (K+C)x(K+C) 的矩阵A,A[i][j]表示物体i和物体j之间的距离,有些物体之间可能没有直接通路. ...
- 【Thinkphp5】封装layer弹窗方法
1 官网下载layer 2 引入文件: <!--layer,官网可下载--> <script type="text/javascript" src="/ ...
- linux主机下的Vmware Workstation配置NAT设置 端口映射-Ubuntu为例
最近折腾虚拟机,由于是在linux下进行的,而相关资料比较少,所以遇到了一些问题. 一个就是配置vmware workstation的NAT设置.因为一般来说,NAT可以共享主机的ip,从而能以主机身 ...
- 移动端touch事件滚动
本来想用在北京欢乐谷手机上用touch事件来模拟局部左右内容滚动里,但在touchmove上下滚动时由于禁止了默认事件而body滚动条不能滚动,虽然可以根据touchmove的坐标来判断方向,但体验效 ...
- Unity3D笔记八 Unity生命周期及动画学习
Unity脚本从唤醒到销毁有着一套比较完善的生命周期,添加任何脚本都必须遵守自身生命周期法则.下面介绍一下生命周期中由系统自身调用的几个比较重要的方法. Update(){}.正常更新,用于更新逻 ...
- phpcms输出logo下拉实例
{pc:content action=" siteid="$siteid" order="listorder ASC"} {loop $data $k ...
- Feature Toggle JUnit
Feature Toggle,简单来说,就是一个开关,将未完成功能的代码屏蔽后发布到生产环境,从而避免多分支的情况.之所以有本文的产生,就是源于此情景.在引入Feature Toggle的同时,我们发 ...
- asp.net SessionState模式的配置及使用
由于项目dll文件变动比较频繁,而保存登陆的状态又保存在Session中,所以导致用户经常无故掉线(PS:dll变动的时候导致Session).有一种方法可以长期保存session,那就是sessio ...
- redis cluster 集群畅谈(三) 之 水平扩容、slave自动化迁移
上一篇http://www.cnblogs.com/qinyujie/p/9029522.html, 主要讲解 实验多master写入.读写分离.实验自动故障切换(高可用性),那么本篇我们就来聊了聊r ...
- iptables综述
1 概述 如下图所示,iptables共有Filter,Nat,Mangle和RAW共四个table,每个table还有若干个chain,每个chain中还包含若干个rule 1.1 Filter t ...