Java 中Map 根據底層資料結構的不同,存在多種不同的實現,常見如散列 HashMap ,鏈表linkedMap ,散列鏈表linkedHashMap ,樹形表(二叉樹) TreeMap 等。
本文討論的是我們編程中最為常用的HashMap 散列表的 幾種不同的遍曆方式,及各方式間在寫法和效率上的比較。
首先準備一個Map 散列表,儲存十萬條記錄。
key 是從key0 開始一直到 key99999
value 從hello0 開始一直到 hello99999
public static void main(String[] args) { Map<String,Object> map=new HashMap<String,Object>(); for(int i=0;i<100000;i++){ map.put("key"+i, "hello"+i); } }
遍曆方式一 : entrySet() + 增強for迴圈
// Map 遍曆方式一 //2425.7 static void iterator_type1(Map<String,Object> map){ Set<Map.Entry<String, Object>> set= map.entrySet(); long start=new Date().getTime(); for(Map.Entry<String, Object> item :set){ String key=item.getKey(); Object value=item.getValue(); System.out.println("key:"+key+" "+"value:"+value); } long end=new Date().getTime(); System.out.println("遍曆耗時為:"+(end-start)+" 毫秒"); }
遍曆方式二:entrySet() +iterator迭代
//Map 遍曆方式二 2408.9 static void iterator_type2(Map<String,Object> map){ Set<Map.Entry<String, Object>> set= map.entrySet(); Iterator<Map.Entry<String, Object>> it= set.iterator(); long start=new Date().getTime(); while(it.hasNext()){ Map.Entry<String, Object> item= it.next(); String key=item.getKey(); Object value=item.getValue(); System.out.println("key:"+key+" "+"value:"+value); } long end=new Date().getTime(); System.out.println("遍曆耗時為:"+(end-start)+" 毫秒"); }
遍曆方式三:keySet() + iterator迭代
//Map 遍曆方式三 2441.0 static void iterator_type3(Map<String,Object> map){ Set<String> keys= map.keySet(); Iterator<String> it=keys.iterator(); long start=new Date().getTime(); while(it.hasNext()){ String key=it.next(); Object value=map.get(key); System.out.println("key:"+key+" "+"value:"+value); } long end=new Date().getTime(); System.out.println("遍曆耗時為:"+(end-start)+" 毫秒"); }
遍曆方式四:keySet() + 增強for迴圈
//Map 遍曆方式四 2445.5 static void iterator_type4(Map<String,Object> map){ Set<String> keys= map.keySet(); long start=new Date().getTime(); for(String key :keys){ Object value=map.get(key); System.out.println("key:"+key+" "+"value:"+value); } long end=new Date().getTime(); System.out.println("遍曆耗時為:"+(end-start)+" 毫秒"); }
每種方式均在main函數中調用10次,統計每次遍曆的耗時資料如下。
public static void main(String[] args) { Map<String,Object> map=new HashMap<String,Object>(); for(int i=0;i<100000;i++){ map.put("key"+i, "hello"+i); } // iterator_type1(map);//2425.7 // iterator_type2(map); //2408.9 // iterator_type3(map); //2441.0 //iterator_type4(map);//2445.5}
單位 毫秒 遍曆方式一: 2385 2374 2357 2371 2424 2490 2528 2371 2490 2467 平均耗時 2425.7
遍曆方式二: 2385 2503 2386 2334 2401 2406 2394 2414 2428 2438 平均耗時 2408.9
遍曆方式三: 2391 2401 2481 2471 2423 2436 2481 2449 2414 2463 平均耗時 2441.0
遍曆方式四: 2471 2392 2545 2365 2463 2465 2487 2428 2414 2425 平均耗時 2445.5
從測試的結果資料中可以看出,在以上四種遍曆方式中。採用entrySet 方式 普遍比keySet方式效率高;採用entrySet中的 iterator方式又比增強for的效率高。
遍曆效率最高的方式為 entrySet+iterator 方式,其次entrySet+增強for ,再次keySet+iterator,最次keySet+增強for
----以上結論僅供參考, 純個人測試得出的結論,並無實際的理論依據。