1. 程式人生 > >哪種Map遍歷方法更優?!—Map遍歷方法的正確選擇

哪種Map遍歷方法更優?!—Map遍歷方法的正確選擇

我們都知道遍歷Map一般有3種方法,values(),keySet()和entrySet(),常見的是keySet用的多,簡單容易理解,entrySet()是返回Map中的靜態內部類Entry類型別的Set例項,當然了你別說forEach,forEach只是一種代替for(int i=0;;)和while()遍歷的一種方式,底層也是用迭代器實現的,只不過把部分東西隱藏了,建議大家平常開發中能用forEach遍歷,儘可能的用這個,《Effective java》中也明確表示了,簡單而不容易出錯。
如果Map中有大量的元素,而且併發量又很高,這就涉及到採用哪種遍歷方法的問題,下面就來測試一下:

  1.               Map<String,String> mapTest=
    new HashMap<String,String>();  
  2. for(int i=0;i<10000;i++){  
  3.     mapTest.put(String.valueOf(i),String.valueOf(i) );  
  4. }  
  5. //一種遍歷,keySet()方法
  6. long start=System.nanoTime();  
  7. Set<String> setEach=mapTest.keySet();  
  8. for(String key:setEach){  
  9.     String value=mapTest.get(key);  
  10. }  
  11. long end=System.nanoTime();  
  12. System.out.println("keySet遍歷map耗時"+(end-start)/1000+"微秒");  
  1. //二種遍歷,可用values()返回Collection<T>,不容易得到對應的key
  2. start=System.nanoTime();  
  3. Collection<String> co=mapTest.values();  
  4. for(String value:co){  
  5.     //遍歷中也在建立value
  6. }  
  7. end=System.nanoTime();  
  8. System.out.println("values遍歷map(只得到值)耗時"+(end-start)/1000+"微秒"
    );  
  1. //三種遍歷,用entrySet()方法返回Set<Map.Entry<T,T>>型別,再獲取裡邊的Map.Entry
  2. start=System.nanoTime();  
  3. Set<Map.Entry<String,String>> entrySet=mapTest.entrySet();  
  4. for(Map.Entry<String, String> entry:entrySet){  
  5.     String key=entry.getKey();  
  6.     String value=entry.getValue();  
  7. }  
  8. end=System.nanoTime();  
  9. System.out.println("entrySet遍歷map耗時"+(end-start)/1000+"微秒");  

經過多次執行,結果大概都是這樣的:

  1. keySet遍歷map耗時9867微秒  
  2. values遍歷map(只得到值)耗時2539微秒  
  3. entrySet遍歷map耗時2783微秒  

       values()是返回Map的所有value的集合collection,只能遍歷到值,很難遍歷到key所以一般不用,除非在某種特殊場合,所以一般採用的第一種和第三種方式。而測試表明entrySet()方式遍歷效率更高。
       entrySet()方式遍歷之所以快與keySet(),一個原因是keySet相當與遍歷了2次,一次是對key的Set集合的遍歷,二次是每次遍歷過程都要通過key和map.get(key)來獲取value值。第二個原因是map.get(key)獲取的時候,底層其實根據key的hashcode值經過雜湊演算法得到一個hash值然後作為索引對映到對應table陣列的索引位置,這是一次密集型計算,很耗費CPU,如果有大量的元素,則會使CPU使用率飆升,影響響應速度,而entrySet()返回的set裡邊元素都是Map.Entry型別,key和value就是這個類的一個屬性,entry.getKey()和entry.getValue()效率肯定很高。
       所以平常開發過程中,如果對Map講究效率的遍歷的話,還是採用entrySet()方法。