-
2017-10-12 10:32:13
Java中的Map遍历
推荐使用entrySet遍历Map类集合KV,而不是keySet方式进行遍历。
说明:keySet其实是遍历了2次,一次是转为Iterator对象,另一次是从hashMap中取出key所对应的value。
而entrySet只是遍历了一次就把key和value都放到了entry中,效率更高。如果是JDK8,使用Map.foreach方法。
更多相关内容 -
高效编程之HashMap的entryset和keyset比较
2017-04-11 14:32:21最近看了一点spring的源码,甚是苦涩;对spring稍微有了点整体的认识,但对很多细节的地方还是懵逼啊。。。太多不懂了的,只能慢慢去读,先把简单的不懂的解决;...再往下面走的,这个entryset方法我不最近看了一点spring的源码,甚是苦涩;对spring稍微有了点整体的认识,但对很多细节的地方还是懵逼啊。。。太多不懂了的,只能慢慢去读,先把简单的不懂的解决;
比如beanfactory通过扫描器拿到了注解标记的那些类,都是放到一个hashmap中,然后文件名就是key,文件就是value;首先都会有一个 "map".entryset的操作;再往下面走的,这个entryset方法我不太明白是啥意思,看了1.6的API,告诉我返回一个set视图,这样的翻译感觉略水...直接告诉我返回set集合不就好了么...
废话不多说,进入正题;
hashmap里存的是entry对象,一个entry对象由key,value组成;
我们会把数据放到value,如果想拿的话可以通过key去取,也可以直接从entry对象里去拿;
所以如果我们拿到了一个有"东西"的hashmap的时候,我们可以有两种方式拿到里面的value;
一种是keyset(),一种是entryset(),但是这两个方法哪个效率更高,使你的代码更棒呢?
看jvm给我们的答案;
上代码!
输入结果:public class HashMapTest { public static void main(String[] args) { HashMap<Integer,String> hashmap = new HashMap<Integer,String>(); for (int i = 0; i < 10000000; i++ ){ hashmap.put(i, "glsx"); } long bs = Calendar.getInstance().getTimeInMillis(); Iterator iterator = hashmap.keySet().iterator(); while (iterator.hasNext()) { hashmap.get(iterator.next()); } System.out.print("keyset:"); System.out.println(Calendar.getInstance().getTimeInMillis() - bs); listHashMap(); } public static void listHashMap(){ HashMap<Integer,String> hashmap = new HashMap<Integer,String>(); for (int i = 0; i < 10000000; i++ ) { hashmap.put(i, "glsx"); } long bs = Calendar.getInstance().getTimeInMillis(); Iterator it = hashmap.entrySet().iterator(); while (it.hasNext()) { Map.Entry entry = (Map.Entry) it.next(); entry.getValue(); } System.out.print("entryset:"); System.out.println(Calendar.getInstance().getTimeInMillis() - bs); } }
多测试几次的输入结果:keyset:168 entryset:76
结果很明显,entryset速度比keyset快了两倍多点;keyset:171 entryset:70 ======= keyset:169 entryset:81 ======= keyset:175 entryset:74
hashmap.entryset,在set集合中存放的是entry对象。而在hashmap中的key 和 value 是存放在entry对象里面的;然后用迭代器,遍历set集合,就可以拿到每一个entry对象;得到entry对象就可以直接从entry拿到value了;
而hashmap.keyset只是把hashmap中key放到一个set集合中去,还是通过迭代器去遍历,然后再通过 hashmap.get(key)方法拿到value;差别在哪里呢? 源码给我们答案了。
entry.getvalue可以直接拿到value,hashmap.get(key)是先得到Entry对象,再通过entry.getvalue去拿,直白点说就是hashmap.get(key)走了一个弯路,所以它慢一些;public V get(Object key) { if (key == null) return getForNullKey(); Entry<K,V> entry = getEntry(key); return null == entry ? null : entry.getValue(); }
所以我们以后遍历hashmap想要拿value的时候能记得多用entryset()哈~
-
HashMap使用EntrySet与KeySet的区别(快慢比较),你测试方法对了么?
2021-01-13 17:12:30最近在csdn搜索了关于EntrySet与KeySet的效率问题,发现很多说entrySet快,但是都是好几年前的,而且... * 测试Map的keySet和entrySet的性能 * * @author yangbiao * @date 2021/1/13 15:31 */ public class Test {最近在csdn搜索了关于EntrySet与KeySet的效率问题,发现很多说entrySet快,但是都是好几年前的,而且看他给的源码跟我点开jdk的源码不一致应该是jdk版本不同,另外也有说自己测试结果发现keySet快的,那么到底如何呢?还是得自己验证一下。
我用的是jdk1.8测试的,代码如下
/** * 测试Map的keySet和entrySet的性能 * * @author yangbiao * @date 2021/1/13 15:31 */ public class Test { HashMap<String,String> map; @BeforeEach void setUp() { map = new HashMap<>(); for(int i = 0; i <= 1000000; i++){ map.put("key-" + i, "value-" + i); } } @org.junit.jupiter.api.Test void testKeySet() { StringBuilder sb = new StringBuilder(); long startTime = System.currentTimeMillis(); for( String s : map.keySet()){ sb.append(s).append(map.get(s)); } long kTime = System.currentTimeMillis() - startTime; System.out.println("字符串长度:"+sb.length()); System.out.println("keySet花费: " + kTime); } @org.junit.jupiter.api.Test void testEntrySet() { StringBuilder sb = new StringBuilder(); long startTime = System.currentTimeMillis(); for( Map.Entry<String, String> e : map.entrySet()){ //将map的key和value进行拼接 sb.append(e.getKey()).append(e.getValue()); } long eTime = System.currentTimeMillis() - startTime; System.out.println("字符串长度:"+sb.length()); System.out.println("entrySet花费: " + eTime); } @org.junit.jupiter.api.Test void testTogether() { System.out.println("先测试keySet再测试entrySet"); testKeySet(); testEntrySet(); } @org.junit.jupiter.api.Test void testTogetherAgain() { System.out.println("先测试entrySet再测试keySet"); testEntrySet(); testKeySet(); } @org.junit.jupiter.api.Test void testTogetherBy2Thread() throws InterruptedException { //创建两个线程分别测试 Thread thread1 = new Thread(this::testKeySet); Thread thread2 = new Thread(this::testEntrySet); thread1.start(); thread2.start(); Thread.sleep(4000); } @org.junit.jupiter.api.Test void testTogetherBy2ThreadAgain() throws InterruptedException { //创建两个线程分别测试 Thread thread1 = new Thread(this::testEntrySet); Thread thread2 = new Thread(this::testKeySet); thread1.start(); thread2.start(); Thread.sleep(4000); } }
定义一个
HashMap
,每个测试方法都初始化一次,有6个测试方法,分别是测试keySet,entrySet,keySet+entrySet,entrySet+keySet,keySet+entrySet两个线程执行,entrySet+keySet两个线程执行。为什么要这样写测试方法,因为我发现网上给的很多测试是在同一个方法里进行测试的,我就交换了下顺序,发现结果竟然是后面的总是慢于前面的。这或许是java编译器优化了?我也不清楚。单个方法进行测试结果会有误差不好判断,所以方法1和2的结果都没有参考性可言。
运行方法3和4即
testTogether()
跟testTogetherAgain()
是截然相反的结果。
运行方法5和6即
testTogetherBy2Thread()
跟testTogetherBy2ThreadAgain()
,用两个线程不同加入顺序执行测试。
表明entrySet略快于keySet,再增加一倍的数据,测试如下
证明entrySet快于keySet。 -
entryset和keyset
2018-05-09 14:02:30package com.wuyuan.demo; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; ... //方法一: 用entrySet() public void test1() {...package com.wuyuan.demo; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; public class TestMap { //方法一: 用entrySet() public void test1() { Map<String, String> map = new HashMap<String, String>(16); map.put("name", "lihua"); map.put("age", "16"); map.put("hobby", "apple"); StringBuilder sb = new StringBuilder(); Iterator<Entry<String, String>> iterator = map.entrySet().iterator(); while (iterator.hasNext()) { Entry<String, String> next = iterator.next(); String str1 = next.getKey(); String str2 = next.getValue(); sb.append(str1+str2+"......"); } System.out.println(sb.toString()); } // 方法二:jdk1.8支持,用entrySet()和For-Each循环() (强烈建议) public void test2() { Map<String, String> map = new HashMap<String, String>(16); map.put("name", "lihua"); map.put("age", "16"); map.put("hobby", "apple"); StringBuilder sb = new StringBuilder(); for(Map.Entry<String, String> m : map.entrySet()) { String key = m.getKey(); String value= m.getValue(); sb.append(key+value+"......"); } System.out.println(sb.toString()); } public void test3() { Map<String, String> map = new HashMap<String, String>(16); map.put("name", "lihua"); map.put("age", "16"); map.put("hobby", "apple"); // 方法三:用keySet() Iterator<String> it2 = map.keySet().iterator(); while (it2.hasNext()){ String key = it2.next(); String value= map.get(key); } } public void test4() { Map<String, String> map = new HashMap<String, String>(16); map.put("name", "lihua"); map.put("age", "16"); map.put("hobby", "apple"); // 方法四:jdk1.5支持,用keySet()和For-Each循环 for(String m: map.keySet()){ String key = m; String value= map.get(m); } } public static void main(String[] args) { TestMap tm = new TestMap(); tm.test2(); } }
foreach的内部原理其实还是 Iterator,但它不能像Iterator一样可以人为的控制,而且也不能调用iterator.remove(),更不能使用下标来方便的访问元素。因此foreach这种循环一般只适合做数组的遍历,提取数据显示等,不适合用于增加删除和使用下标等复杂的操作。
阿里巴巴java开发规范说明如下:
-
Map对象中keyset()和entryset()区别
2018-04-23 14:56:47entrySet() //返回映射所包含的映射关系的Set集合(一个关系就是一个键-值对),就是把(key-value)作为一个整体一对一对地存放到Set集合当中的。下面通过例子看看:一. keySet()方式。1234567891... -
map中entrySet和KeySet的区别
2020-01-17 14:50:27 -
keySet()和entrySet()的区别
2021-11-19 11:12:23Map集合中value()方法与keySet()、entrySet()区别 在Map集合中 values():方法是获取集合中的所有的值----没有键,没有对应关系, KeySet(): 将Map中所有的键存入到set集合中。因为set具备迭代器。所有可以迭代... -
HashMap中entrySet()与keySet()的区别
2019-07-28 12:53:06Map<String,Object>...1.entrySet()返回的是一个Set<Entry<String>,Object>类型。所以需要Set<Entry<String>,object> 来接收它。 例如 : Set<Entry<Strin... -
Map 中的 keySet() 和 entrySet() 区别
2018-02-22 15:16:40比较常用的 keySet():HashMap<String,String> hm = new HashMap<String,String>(); hm.put("name", "pioneer"); hm.put("age", "12"); ... -
keySet和entrySet
2019-08-08 11:36:53使用entrySet则必须将map对象转换为Map.Entry,keySet则不需要 KeySet(): 将Map中所有的键存入到set集合中,因为set具备迭代器,所有可以迭代方式取出所有的键,通过**e.get(key)**方法取值 ; entrySet(): S... -
EntrySet与KeySet遍历Map及性能对比
2018-08-28 13:42:29遍历Map时,主要使用的是EntrySet以及KeySet这两种遍历方法。 以下是实现两种遍历方式的代码: import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.u... -
keySet()和entrySet()
2021-04-21 15:25:36keySet()和entrySet(),是Map集合中的两种取值方法。 与get(Objectkey)相比,get(Objectkey)只能返回到指定键所映射的值,不能一次全部取出。而keySet()和entrySet()可以。 Map集合中没有迭代器,Map集合取出键值... -
遍历Map的几种方法 entrySet 和 keySet
2018-06-07 10:25:54Map.entrySet() Map.keySet() 首先这两种方法返回的都是Set集合, 区别在于,第一种集合里是 Map.entry (会有key-value的键值对)类型的对象; 而第二种集合里是String对象(假设创建Map时key值是String类型的... -
EntrySet比KeySet效率高
2014-03-05 14:57:31import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.Iterator;... * 测试keySet()与entrySet()的迭代时间 * keySet():迭代后只能通过get()取... -
使用entrySet、keySet俩种方式对map集合进行遍历
2019-12-20 21:15:11//通过entryset和set两种方式对容器进行遍历 // //1、通过entryset方式遍历 // Set,String>> entry = map.entrySet(); // //获取迭代器 // //遍历 // for (Map.Entry, String> en : entry) { // //使用... -
java中Map的entrySet 和keySet的使用
2018-06-02 10:45:00可以通过调用 entrySet方法 或者 keySet方法 进行迭代或者增强for循环 便利输出 这里演示 迭代器的方式进行遍历 package demo05; import java.util.HashMap; import java.util.Iterator; import java... -
HashMap的两种遍历方法EntrySet或者KeySet性能分析
2020-04-24 10:56:461.迭代器entrySet Map map = new HashMap(); Iterator iter = map.entrySet().iterator(); while (iter.hasNext()) { Map.Entry entry = (Map.Entry) iter.next(); Object key = en... -
遍历Map类集合的KV的方式?entrySet和keySet的区别?
2019-10-31 18:06:11我知道的有两种常用的方式:keySet(),entrySet()。 还有一种是通过Map.values()遍历所有的value,但不能遍历key (1)keySet()返回的是 K 值集合,是一个 Set 集合对象 最后根据get方法。获取每一个键对应的值 Map&... -
如何遍历Map,map的keySet()和EntrySet()区别
2018-08-05 21:31:41如何遍历Map,map的keySet()和EntrySet()区别 遍历map public static void main(String[] args) { // TODO Auto-generated method stub Map<String, Student> map = new HashMap<String,... -
JAVA中Map使用keySet()和entrySet()进行遍历效率的对比
2018-12-10 15:22:10如果想要遍历Map的话,是使用keySet()方法还是entrySet()方法呢?在我近期的项目中,我就选择使用了keySet()方法来遍历Map,最后在验收时使用FindBug做静态代码检测时没有通过验收,最终无奈就改用了entrySet()方法... -
entrySet 和 keySet 的区别
2012-01-14 11:59:19看了网上一些文章,都说keySet比entrySet慢。 我测试下来两者区别不大。 而且用keySet更加简单 [code="java"] import java.util.Calendar; import java.util.*; import java.util.HashMap; import ... -
Map集合的entrySet和keySet
2020-05-08 13:48:15List<Student> ls=new ArrayList();... // } //利用的Map.Entry for(Map.Entry, List<Student>> en : collect.entrySet()){ System.out.println(en.getValue()); System.out.println(en.getKey()); } 参考文章 -
keySet和entrySet速度区别
2016-01-16 21:49:521、keySet()的速度比entrySet()慢了很多,也就是...对于keySet来讲,他便利了两次,一次转为Iterator类型,一次成HashMap中取出key对应的value值,二entrySet只遍历了一次,他将key和value全部放入entry中。 2、k -
HashMap(2): EntrySet、KeySet实现原理
2017-03-16 19:39:29一....因此,我们有3种对数据的观测方式:keySet,values,entrySet。keySet是从key的值角度出发的结果。它里面包含了这个键值对表里面的所有键的值的集合,因为HashMap明确规定一个键只能对应一个值 -
Map.entrySet和Map.keySet执行效率比较
2019-01-03 17:59:18Map.entrySet是直接一次性获取map的所有键值对,可以通过getKey和getValue来获取健和值。 Map.keySet获取map的健,获取值需要再一次使用map.get()方法来获取对应的值。 所以可以看出,Map.entrySet比Map.keySet少... -
Java中遍历Map的方法:entrySet(),和keySet()
2022-02-13 16:17:20entrySet()方法会返回key-value实体对的集合,此集合的类型即为Map.Entry,遍历时可以直接使用Map.Entry接口中的getKey(),getValue()方法; keySet()则返回的是key的集合,需要在使用get()方法从map中取数据。 ... -
Map对象中的KeySet()与EntrySet()的区别
2019-10-08 17:28:40Map中的KeySet()与EntrySet()方法 Map集合提供了get()方法获取元素,但是get()对应的是一个键取出值,这种方式比较局限和单一,不能一次性全部取出来。要取出所有的值,就必须要取出所有的键,然后才能获取全部与键... -
Map对象中keyset()和entryset()遍历的区别
2018-11-13 11:13:43keySet()://返回值是个只存放key值的Set集合(集合中无序存放的) Set<Map.Entry<K,V>> entrySet(): //返回映射所包含的映射关系的Set集合(一个关系就是一个键-值对), 就是把...