在原始記憶中,Java HashMap遍歷,無非是for each或者iterator,但至於在遍歷時性能如何,優缺點如何,泛泛而不得知。對於這樣的基礎問題,對於王二(Java編程6年,幸好我的方向不是編程)我來說,似乎羞於提及,但事實證明,我還必須“積硅步”。
該種方法是我使用最頻繁的,沒有之一,詳見如下代碼:
Map map = new HashMap();
addMap(map);
long t1 = System.currentTimeMillis();
Iterator keys = map.keySet().iterator();
while (keys.hasNext()) {
Integer key = keys.next();
Integer value = map.get(key);
keys.remove();
}
long t2 = System.currentTimeMillis();
System.out.println("map.keySet().iterator()耗時:" + (t2 - t1));
以前的我看來,該種方法使用起來相當簡潔,通過iterator遍歷出來keys,然後通過key從map中獲取對應的value,似乎也非常接地氣。但是,弊端就在於
它更慢更低效,通過key得到value值更耗時(這個方法在所有實現map接口的map中比方法#1慢20%-200%)。如果你安裝了FindBugs,它將檢測並警告你這是一個低效的迭代。這個方法應該避免
看到這條信息,我是覺得有點唐突,怎麼原來最喜歡的一種map遍歷方式竟然如此low,簡直讓人失望。後面我會對花費的性能時間做一個統計,稍候關注。
這種方法我以前幾乎不用,但方法二卻有其關鍵的優點:
可以通過iterator對map的元素進行刪除。方法一同樣。性能優良。
Map map = new HashMap();
addMap(map);
long t3 = System.currentTimeMillis();
Iterator> entrys = map.entrySet().iterator();
while (entrys.hasNext()) {
Entry entry = entrys.next();
Integer key = entry.getKey();
Integer value = entry.getValue();
entrys.remove();
}
long t4 = System.currentTimeMillis();
System.out.println(" map.entrySet().iterator()耗時:" + (t4 - t3));
通過“map.entrySet().iterator()”獲得map的entry對象,然後通過getKey,getValue進行key和value值得獲取,非常的直白和實用。
for each一個局限是不同remove map中的元素,但遍歷map還是非常好的。
Map map = new HashMap();
addMap(map);
long t5 = System.currentTimeMillis();
for (Integer key : map.keySet()) {
}
for (Integer value : map.values()) {
}
long t6 = System.currentTimeMillis();
System.out.println("for each map.keySet()、map.values()耗時:" + (t6 - t5));
不過這裡,王二有話要說,按照stackoverflow上所說,該種方法要比接下來說的第四種方法“For-Each迭代entries”性能更好(大約快10%),但在我的實踐中並非如此,這種方法反而比第四種“For-Each迭代entries”慢得多。
Map map = new HashMap();
addMap(map);
long t7 = System.currentTimeMillis();
for (Entry entry : map.entrySet()) {
Integer key = entry.getKey();
Integer value = entry.getValue();
}
long t8 = System.currentTimeMillis();
System.out.println("for each map.entrySet()耗時:" + (t8 - t7));
這種方法就不多做介紹了。
可以總結如下:
迭代keys並搜索values 非常低效,排名幾乎在倒數第一或第二 For-Each迭代entries 性能最佳,但無法remove For-Each迭代keys和values並沒有比For-Each迭代entries 性能(大約快10%),stackoverflow上的數據也不能全部苟同 Iterator迭代Entry 的方案顯然最適合使用,性能優良,且可以remove