- 浏览: 163707 次
- 来自: ...
文章分类
最新评论
-
hellostory:
不知所云………………
如何使用反射访问类的private域和方法 -
xusong_zidingyi:
如果在linux下面的话就没有办法运行了,因为linux没有办 ...
使用tesseract破解checkCode -
javajava22:
Errors accessing files. There m ...
使用tesseract破解checkCode -
suncathay:
qljobs 写道cmd.add("E:/Works ...
使用tesseract破解checkCode -
zuoxu128:
TIFFImageWriteParam ,这个类是哪个包的啊
使用tesseract破解checkCode
首先,遍历map有以下方法:
import java.util.HashMap; import java.util.Iterator; import java.util.Map; public class MapTest { public static void main(String[] args) { Map<String, String> map = new HashMap<String, String>(); map.put("1", "1"); map.put("2", "2"); map.put("3", "3"); // 第一种:通过Map.keySet遍历key和value System.out.println("通过Map.keySet遍历key和value:"); for (String key : map.keySet()) { System.out.println("key= " + key + " and value= " + map.get(key)); } // 第二种:通过Map.entrySet使用iterator遍历key和value System.out.println("通过Map.entrySet使用iterator遍历key和value:"); Iterator<Map.Entry<String, String>> it = map.entrySet().iterator(); while (it.hasNext()) { Map.Entry<String, String> entry = it.next(); System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue()); } // 第三种:通过Map.entrySet遍历key和value System.out.println("通过Map.entrySet遍历key和value:"); for (Map.Entry<String, String> entry : map.entrySet()) { System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue()); } // 第四种:通过Map.values()遍历所有的value,但是不能遍历键key System.out.println("通过Map.values()遍历所有的value:"); for (String v : map.values()) { System.out.println("value= " + v); } } }
结果如下:
通过Map.keySet遍历key和value: key= 3 and value= 3 key= 2 and value= 2 key= 1 and value= 1 通过Map.entrySet使用iterator遍历key和value: key= 3 and value= 3 key= 2 and value= 2 key= 1 and value= 1 通过Map.entrySet遍历key和value: key= 3 and value= 3 key= 2 and value= 2 key= 1 and value= 1 通过Map.values()遍历所有的value: value= 3 value= 2 value= 1
这四种方法都可以遍历map:
第一种是目前许多人最喜欢的一种方式,因为代码最少,看起来最简单,通过遍历keySet,再将key所对应的value查询出来,这里有一个二次取值的过程,所以并不推荐;
第二种和第三种原理是相同的,都是通过遍历Map.Entry的方式,将Entry中的key和value打印出来,第三种是比较推荐写法,因为采用jdk1.5后的遍历形式,代码看起来比较整洁;
第四种比较少用,因为我们大多数时候都是同时需要key和value的
综上所述,如果map里面内容比较少,其实采用哪种方式都可以,第一种和第三种相对简洁一些;但是一旦容量非常大时,更推荐采用第三种方式,相比于第一种将极大地节省性能。
修改一下代码,对执行时间执行一下测试
import java.util.HashMap; import java.util.Map; public class MapTest { static long MAX_LONG = 1000000L; static int TIMES = 10; static Map<String, String> map1 = new HashMap<String, String>(); static Map<String, String> map2 = new HashMap<String, String>(); static { for (long i = 0; i < MAX_LONG; i++) { map1.put("1" + i, "abc" + i); map2.put("2" + i, "def" + i); } } public static void main(String[] args) { String valueStr = ""; String keyStr = ""; long start, end; double totalMs; totalMs = 0; for (int i = 0; i < TIMES; i++) { // 通过Map.keySet遍历key和value start = System.currentTimeMillis(); for (String key : map1.keySet()) { keyStr = key; valueStr = map1.get(key); } end = System.currentTimeMillis(); System.out.println("通过Map.keySet遍历key和value耗时 " + (end - start) + " ms "); totalMs += (end - start); } System.out.println("Times : " + TIMES + ", totalMs : " + totalMs + "ms, average :" + totalMs / TIMES + "ms"); totalMs = 0; for (int i = 0; i < TIMES; i++) { // 通过Map.entrySet遍历key和value start = System.currentTimeMillis(); for (Map.Entry<String, String> entry : map2.entrySet()) { keyStr = entry.getKey(); valueStr = entry.getValue(); } end = System.currentTimeMillis(); System.out.println("通过Map.entrySet遍历key和value耗时 " + (end - start) + " ms "); totalMs += (end - start); } System.out.println("Times : " + TIMES + ", totalMs : " + totalMs + "ms, average :" + totalMs / TIMES + "ms"); } }
以下是测试结果:
通过Map.keySet遍历key和value耗时 186 ms 通过Map.keySet遍历key和value耗时 189 ms 通过Map.keySet遍历key和value耗时 87 ms 通过Map.keySet遍历key和value耗时 89 ms 通过Map.keySet遍历key和value耗时 84 ms 通过Map.keySet遍历key和value耗时 92 ms 通过Map.keySet遍历key和value耗时 85 ms 通过Map.keySet遍历key和value耗时 94 ms 通过Map.keySet遍历key和value耗时 89 ms 通过Map.keySet遍历key和value耗时 91 ms Times : 10, totalMs : 1086.0ms, average :108.6ms 通过Map.entrySet遍历key和value耗时 112 ms 通过Map.entrySet遍历key和value耗时 98 ms 通过Map.entrySet遍历key和value耗时 71 ms 通过Map.entrySet遍历key和value耗时 65 ms 通过Map.entrySet遍历key和value耗时 65 ms 通过Map.entrySet遍历key和value耗时 64 ms 通过Map.entrySet遍历key和value耗时 64 ms 通过Map.entrySet遍历key和value耗时 65 ms 通过Map.entrySet遍历key和value耗时 65 ms 通过Map.entrySet遍历key和value耗时 65 ms Times : 10, totalMs : 734.0ms, average :73.4ms
可以看出,百万级别的量时,使用keySet和entrySet遍历,执行时间大概为1.5:1,这并不是最主要的差异。真正的差异还是必须看代码
map.get(key))
时执行的hash操作
/** * Returns the value to which the specified key is mapped, * or {@code null} if this map contains no mapping for the key. * * <p>More formally, if this map contains a mapping from a key * {@code k} to a value {@code v} such that {@code (key==null ? k==null : * key.equals(k))}, then this method returns {@code v}; otherwise * it returns {@code null}. (There can be at most one such mapping.) * * <p>A return value of {@code null} does not <i>necessarily</i> * indicate that the map contains no mapping for the key; it's also * possible that the map explicitly maps the key to {@code null}. * The {@link #containsKey containsKey} operation may be used to * distinguish these two cases. * * @see #put(Object, Object) */ 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; }
计算hashCode是CPU密集运算,非常耗费CPU资源,如果对一个比较大的map进行遍历,会出现CPU迅速飚高的现象,直接影响机器的响应速度,在多线程的情况下,简直就是一场灾难,而采用entrySet来进行遍历,则无此问题,对这个有兴趣的同学,可以使用自己的机器试一试。
评论
29 楼
chenhongwei0924
2010-12-20
不错。。。 值得学习..
28 楼
fm_974
2010-10-26
有研究精神!赞一个
27 楼
zhang_xzhi_xjtu
2010-10-25
加上静态代码检查工具 就会发现第一种方法会有warn的。
26 楼
Java_Travler
2010-10-25
很好,这样的帖子才应该鼓励和支持!这样大家才有讨论的热点和兴趣!才能学到或更好的理解更多的东西!
25 楼
風一樣的男子
2010-10-24
看过源码的人都知道应该用entrySet遍历
24 楼
ldbjakyo
2010-10-14
再次回来瞧过 比第一次来看 补充了 好多
23 楼
lwz777
2010-10-13
这样的文章才有点味道不是!
22 楼
parabellum_sky
2010-10-13
parabellum_sky 写道
怎么执行第二段代码出错了呢?
Exception in thread "main"
并且啥信息都没有~~
Exception in thread "main"
并且啥信息都没有~~
估计是OOM了,MAX_LONG减少一个数量级以后就可以了~但是看不出来问题~~
21 楼
parabellum_sky
2010-10-13
怎么执行第二段代码出错了呢?
Exception in thread "main"
并且啥信息都没有~~
Exception in thread "main"
并且啥信息都没有~~
20 楼
elan1986
2010-10-12
总结的不错!
19 楼
ansjsun
2010-10-12
su1216 写道
实践证明,不一定哪个快。。。
不过第二个基本上每次都要慢一点
测试map
public static Map<String,String> getMap(long k){
Map map=new HashMap();
for (int i = 0; i <k; i++) {
map.put(""+i,""+i);
}
return map;
}
k=10w
ps:jdk1.5
不过第二个基本上每次都要慢一点
测试map
public static Map<String,String> getMap(long k){
Map map=new HashMap();
for (int i = 0; i <k; i++) {
map.put(""+i,""+i);
}
return map;
}
k=10w
ps:jdk1.5
你用的是linux吧....用windows速度应该比较稳定的...其实大容量map不是考虑..速度..而更应该考虑内存的开销..集合啦..处理海量数据最容易导致..内存当掉了...
如果很追求速度..那也不要用map去做..jdk的自动装箱..本来就是很耗费时间的
18 楼
dengminhui
2010-10-11
呵呵,针对大家的疑问,我写在文章后面了,执行时间只是差异的一方面,最主要的还是CPU。
17 楼
lkj107
2010-10-11
大家都用的就是好方法
代码的执行只是一小部分功能,最大的是可读性,以及由此延伸的可维护性等
代码的执行只是一小部分功能,最大的是可读性,以及由此延伸的可维护性等
16 楼
newvirus
2010-10-11
不错的文章 学习了 私下地下尝试一下
15 楼
helloguoxing
2010-10-11
这样减少了map扩容的次数。不过数据量小了,就不必这样写,直接new HashMap()。
14 楼
helloguoxing
2010-10-11
map的大容量优化方法:
1、提前要知道容量要放多大,只要确保map集合的size<1024*0.75就可以了。
这个1024是自己设置的。可以在new HashMap(1024,0.75);
1024是偶数,在方法hash()-哈希算法中:h & (length-1);(length-1)要确认得出的值是奇数,这样才能解决循环遍历map产生的冲突。
0.75是3/4,因为数组满了不利于数组扩容。所以设计者建议为3/4.
1、提前要知道容量要放多大,只要确保map集合的size<1024*0.75就可以了。
这个1024是自己设置的。可以在new HashMap(1024,0.75);
1024是偶数,在方法hash()-哈希算法中:h & (length-1);(length-1)要确认得出的值是奇数,这样才能解决循环遍历map产生的冲突。
0.75是3/4,因为数组满了不利于数组扩容。所以设计者建议为3/4.
13 楼
su1216
2010-10-11
实践证明,不一定哪个快。。。
不过第二个基本上每次都要慢一点
测试map
public static Map<String,String> getMap(long k){
Map map=new HashMap();
for (int i = 0; i <k; i++) {
map.put(""+i,""+i);
}
return map;
}
k=10w
ps:jdk1.5
不过第二个基本上每次都要慢一点
测试map
public static Map<String,String> getMap(long k){
Map map=new HashMap();
for (int i = 0; i <k; i++) {
map.put(""+i,""+i);
}
return map;
}
k=10w
ps:jdk1.5
12 楼
gh_aiyz
2010-10-11
我打赌第一种和第二三中的性能差别不超过1%,无论你多大容量。
LZ纯粹是臆测罢了,有点想当然了。
LZ纯粹是臆测罢了,有点想当然了。
11 楼
吃猫的鱼
2010-10-10
没说服力啊,,要是把测试结果的性能比较贴出来,就很带劲了……
10 楼
yuantong
2010-10-10
还大容量,最普通不过了
发表评论
-
一些随想
2012-06-01 22:05 0需求 idea 方案 执 ... -
Redis的安装与使用
2011-10-24 20:04 1233今天看了下redis相关的东东,做个备忘。 Re ... -
Redis的安装与使用
2011-10-24 20:00 0Redis 服务端: http://cocos.iteye. ... -
GenericDAO
2011-07-31 14:49 0GenericDAO -
loadfromproperties
2011-07-31 14:48 0loadfromproperties -
resultcode
2011-07-31 14:47 0resultcode -
berkeleydb的使用
2011-10-24 20:05 1801在napoli的代码中发现这个berkeleydb,版本为3. ... -
几种简单的Load Balance方法
2011-07-31 13:44 0以下代码出自napoli (1)定义Selec ... -
参数断言工具
2011-07-31 12:58 907见代码: public final class Argume ... -
如何检测线上代码的运行情况---BTrace使用分享
2011-04-10 17:36 2035(1)你是否有时发现线上的代码运行效率不高,但却无法定位到底具 ... -
napoli和JMS,mq的一些知识
2010-11-26 21:01 01 jms和mq (1)jms activeMQ 应用 h ... -
Taglib基础知识
2010-11-26 12:41 0浅论taglib设计 : http://wenku.bai ... -
java编码问题的一些文章
2010-11-11 17:30 0http://www.iteye.com/topic/8047 ... -
URL在转码的过程中数据丢失
2010-10-25 14:52 0示例代码 import java.io.Unsuppo ... -
B2B-Code Review规范
2010-08-31 10:15 01.目标 凡事知其然还要知其所以然,我们首先需要知道什么 ... -
多线程书写及code review规范
2010-08-31 10:09 14101. 不允许将Calendar用于类的静态成员 ... -
域名白名单检查
2010-08-24 21:05 0首先准备一份白名单名为safe-domain.xml ,如下: ... -
如何使用反射访问类的private域和方法
2010-08-17 21:44 5087如何使用反射访问类的private域和方法?非常简单,由 ... -
FindBugs插件的安装与使用
2010-04-21 10:54 18671 什么是FindBugs FindBugs 是一个静态分析 ... -
JAVA调用ICE接口实践
2010-04-01 11:37 5172最近刚开发了一个需求,使用ICE调用服务器端的接口,过程如下: ...
相关推荐
java遍历大容量map的正确方法.pdf
遍历MAP的几种方法,利用keyset进行遍历,它的优点在于可以根据你所想要的key值得到你想要的 values,更具灵活性
java Map 遍历方法 Map map = new HashMap(); Iterator it = map.entrySet().iterator(); while (it.hasNext()) {
map遍历的三种方法map遍历的三种方法map遍历的三种方法
JavaScript中循环遍历Array与Map的方法小结_.docx
详细介绍啦遍历map的几种方式,好吧,共有四种方式
你知道map的遍历方法有几种吗? 那这几种的区别是什么呢? 那种更简单、高效呢? 我的资源文件将告诉你。
java,利用keySet进行遍历map
NULL 博文链接:https://jsjxqjy.iteye.com/blog/2072705
该文档代码讲述了如何在jsp页面iterator遍历数组、Map、List集合
主要介绍了java遍历Map的几种方法,结合实例形式分析了使用循环与迭代等方法操作Map遍历的相关技巧,需要的朋友可以参考下
Map集合的最常规的遍历方法
js中遍历Map对象的方法 console.log(jsonData);//火狐控制台打印输出: Object { fileNumber="文件编号", fileName="文件名称"} for(var key in jsonData) console.log("属性:" + key + ",值:"+ jsonData[key]);...
java中常用的Map的两种遍历方法...
js遍历map javaScript遍历map的简单实现 var map = { "name" : "华仔", "realname":"刘德华" }; for (var key in map) { console.log("map["+key+"]"+map[key]); } 这样会把map给遍历掉,显示在浏览器上的...
Rayleigh衰落MIMO信道遍历容量的Matlab代码
QT遍历窗体的控件的方法 QT遍历窗体的控件 QT遍历窗体 QT遍历控件 QT遍历所有控件 QT遍历窗体的控件的方法 QT遍历窗体的控件 QT遍历窗体 QT遍历控件 QT遍历所有控件
dui Map遍历方法进行总结: Map.Entry是Map声明的一个内部接口,此接口为泛型,定义为Entry,V>。它表示Map中的一个实体(一个key-value对)。接口中有getKey(),getValue方法。
数据模型: @RequestMapping(/freemarker) @Controller public class FreemarkerController { //测试1 @RequestMapping(/test1) public String test1(Model model){ //向数据模型放数据 model.addAttribute(name...
另一种遍历Map的方式,讲述如何使用java中的map