java中遍歷通過不同的元素遍歷map的方式有3種:1.通過keySet遍歷;2.通過entrySet遍歷;3.獲取values遍歷value。通過不同的方式遍歷又分爲foreach和iterator。因爲本文按照這幾個維度,以不同數據量來分別測試所需時間。
主要測試方法如下:
private static void valuesIterator(Map<String, String> map) { /** values iterator遍歷 */ long start = System.currentTimeMillis(); Iterator it = map.values().iterator(); while (it.hasNext()){ String value = (String)it.next(); } long end = System.currentTimeMillis(); System.out.println("values iterator遍歷耗時:" + (end - start) + "ms"); } private static void valuesForeach(Map<String, String> map) { /** values foreach遍歷 */ long start = System.currentTimeMillis(); for (String value : map.values()){ } long end = System.currentTimeMillis(); System.out.println("values foreach遍歷耗時:"+(end-start)+"ms"); } private static void entryIterator(Map<String, String> map) { /** Map.Entry<K, V> iterator遍歷 */ long start = System.currentTimeMillis(); Iterator it = map.entrySet().iterator(); while (it.hasNext()){ Map.Entry<String,String> entry = (Map.Entry<String,String>)it.next(); String key = entry.getKey(); String value = entry.getValue(); } long end = System.currentTimeMillis(); System.out.println("Map.Entry<K, V> iterator遍歷耗時:"+(end-start)+"ms"); } private static void entryForeach(Map<String, String> map) { /** Map.Entry<K, V> foreach遍歷 */ long start = System.currentTimeMillis(); for (Map.Entry<String,String> entry : map.entrySet()){ String key = entry.getKey(); String value = entry.getValue(); } long end = System.currentTimeMillis(); System.out.println("Map.Entry<K, V> foreach遍歷耗時:" + (end - start) + "ms"); } private static void keySetIterator(Map<String, String> map) { /** keySet iterator遍歷 */ long start = System.currentTimeMillis(); Iterator it = map.keySet().iterator(); while (it.hasNext()){ String key = (String)it.next(); String value = map.get(key); } long end = System.currentTimeMillis(); System.out.println("keySet iterator遍歷耗時:"+(end-start)+"ms"); } private static void keySetForeach(Map<String, String> map) { /** keyset foreach遍歷 */ long start = System.currentTimeMillis(); for (String key : map.keySet()){ String value = map.get(key); } long end = System.currentTimeMillis(); System.out.println("keyset foreach遍歷耗時:"+(end-start)+"ms"); }除此之外,還有一些類似的方法,這裏就不都展示出來了。
private static void test(int n) { System.out.println(); System.out.println("-------------------------"); System.out.println(n+"條數據量測試:"); System.out.println(); Map<String,String> map = new HashMap(); for (int i = 0 ; i < n ; i++){ map.put(i+"aa",i+"ss"); } System.out.println("1.遍歷key - value"); keySetForeach(map); keySetIterator(map); entryForeach(map); entryIterator(map); System.out.println(); System.out.println("2.遍歷key"); keySetKeyForeach(map); keySetKeyIterator(map); entryKeyForeach(map); entryKeyIterator(map); System.out.println(); System.out.println("3.遍歷value"); keySetValueForeach(map); keySetValueIterator(map); entryValueForeach(map); entryValueIterator(map); valuesForeach(map); valuesIterator(map); }
public static void main(String[] args) { test(50000); test(100000); test(1000000); }
這裏通過3個數量級測試:5萬條數據,10萬條數據,100萬條數據。
測試結果:
-------------------------
50000條數據量測試:
1.遍歷key - value
keyset foreach遍歷耗時:16ms
keySet iterator遍歷耗時:13ms
Map.Entry<K, V> foreach遍歷耗時:10ms
Map.Entry<K, V> iterator遍歷耗時:11ms
2.遍歷key
keyset foreach遍歷耗時:8ms
keySet iterator遍歷耗時:7ms
Map.Entry<K, V> foreach遍歷耗時:9ms
Map.Entry<K, V> iterator遍歷耗時:8ms
3.遍歷value
keyset foreach遍歷耗時:11ms
keySet iterator遍歷耗時:12ms
Map.Entry<K, V> foreach遍歷耗時:8ms
Map.Entry<K, V> iterator遍歷耗時:7ms
values foreach遍歷耗時:8ms
values iterator遍歷耗時:8ms
-------------------------
100000條數據量測試:
1.遍歷key - value
keyset foreach遍歷耗時:13ms
keySet iterator遍歷耗時:14ms
Map.Entry<K, V> foreach遍歷耗時:10ms
Map.Entry<K, V> iterator遍歷耗時:13ms
2.遍歷key
keyset foreach遍歷耗時:8ms
keySet iterator遍歷耗時:8ms
Map.Entry<K, V> foreach遍歷耗時:9ms
Map.Entry<K, V> iterator遍歷耗時:10ms
3.遍歷value
keyset foreach遍歷耗時:13ms
keySet iterator遍歷耗時:12ms
Map.Entry<K, V> foreach遍歷耗時:9ms
Map.Entry<K, V> iterator遍歷耗時:8ms
values foreach遍歷耗時:8ms
values iterator遍歷耗時:9ms
-------------------------
1000000條數據量測試:
1.遍歷key - value
keyset foreach遍歷耗時:66ms
keySet iterator遍歷耗時:65ms
Map.Entry<K, V> foreach遍歷耗時:47ms
Map.Entry<K, V> iterator遍歷耗時:47ms
2.遍歷key
keyset foreach遍歷耗時:41ms
keySet iterator遍歷耗時:41ms
Map.Entry<K, V> foreach遍歷耗時:42ms
Map.Entry<K, V> iterator遍歷耗時:42ms
3.遍歷value
keyset foreach遍歷耗時:66ms
keySet iterator遍歷耗時:64ms
Map.Entry<K, V> foreach遍歷耗時:43ms
Map.Entry<K, V> iterator遍歷耗時:43ms
values foreach遍歷耗時:42ms
values iterator遍歷耗時:44ms
結果分析:
這裏暫時不對key - value的複雜度、離散程度已經衝突進行測試,僅以簡單的數字字符爲主測試。
hashmap:
1.遍歷key - value的時候,通常情況下,使用entrySet遍歷比keySet更好,因爲keySet要先拿到key,後查出value。
2.遍歷key的時候,通常情況下,使用keySet遍歷比entrySet更好,畢竟entrySet除了包含key之外還有value,需要更多的資源。
3.遍歷value的時候,通常情況下,使用values最方便,其次entrySet。
4.遍歷的方式推薦使用foreach循環,理由有二:1.性能稍好一些;2.代碼簡潔。
5.數據量越大,這種性能差異越明顯。
treemap:
使用treemap測試,結論與hashmap一致,由於其查詢特性決定,上述結論更加明顯。