小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

主要介紹HashMap的四種循環(huán)遍歷方式,各種方式的性能測試對比,根據(jù)HashMap的源碼實現(xiàn)分析性能結(jié)果,總結(jié)結(jié)論

 月影曉風 2015-11-13

主要介紹HashMap的四種循環(huán)遍歷方式,各種方式的性能測試對比,根據(jù)HashMap的源碼實現(xiàn)分析性能結(jié)果,總結(jié)結(jié)論

 

1. Map的四種遍歷方式
下面只是簡單介紹各種遍歷示例(以HashMap為例),各自優(yōu)劣會在本文后面進行分析給出結(jié)論。

(1) for each map.entrySet()

Java
1
2
3
4
5
Map<String, String> map = new HashMap<String, String>();
for (Entry<String, String> entry : map.entrySet()) {
entry.getKey();
entry.getValue();
}

 

(2) 顯示調(diào)用map.entrySet()的集合迭代器

Java
1
2
3
4
5
6
Iterator<Map.Entry<String, String>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, String> entry = iterator.next();
entry.getKey();
entry.getValue();
}

 

(3) for each map.keySet(),再調(diào)用get獲取

Java
1
2
3
4
Map<String, String> map = new HashMap<String, String>();
for (String key : map.keySet()) {
map.get(key);
}

 

(4) for each map.entrySet(),用臨時變量保存map.entrySet()

Java
1
2
3
4
5
Set<Entry<String, String>> entrySet = map.entrySet();
for (Entry<String, String> entry : entrySet) {
entry.getKey();
entry.getValue();
}

在測試前大家可以根據(jù)對HashMap的了解,想想上面四種遍歷方式哪個性能更優(yōu)。

 

2、HashMap四種遍歷方式的性能測試及對比
以下是性能測試代碼,會輸出不同數(shù)量級大小的HashMap各種遍歷方式所花費的時間。

HashMap循環(huán)遍歷方式性能對比測試代碼

PS:如果運行報異常in thread “main” java.lang.OutOfMemoryError: Java heap space,請將main函數(shù)里面map size的大小減小。

其中g(shù)etHashMaps函數(shù)會返回不同size的HashMap。
loopMapCompare函數(shù)會分別用上面的遍歷方式1-4去遍歷每一個map數(shù)組(包含不同大小HashMap)中的HashMap。
print開頭函數(shù)為輸出輔助函數(shù),可忽略。

 

測試環(huán)境為Windows7 32位系統(tǒng) 3.2G雙核CPU 4G內(nèi)存,Java 7,Eclipse -Xms512m -Xmx512m
最終測試結(jié)果如下:

Java
1
2
3
4
5
6
7
8
9
10
11
12
compare loop performance of HashMap
-----------------------------------------------------------------------
map size               | 10,000    | 100,000   | 1,000,000 | 2,000,000
-----------------------------------------------------------------------
for each entrySet      | 2 ms      | 6 ms      | 36 ms     | 91 ms    
-----------------------------------------------------------------------
for iterator entrySet  | 0 ms      | 4 ms      | 35 ms     | 89 ms    
-----------------------------------------------------------------------
for each keySet        | 1 ms      | 6 ms      | 48 ms     | 126 ms    
-----------------------------------------------------------------------
for entrySet=entrySet()| 1 ms      | 4 ms      | 35 ms     | 92 ms    
-----------------------------------------------------------------------

表橫向為同一遍歷方式不同大小HashMap遍歷的時間消耗,縱向為同一HashMap不同遍歷方式遍歷的時間消耗。
PS:由于首次遍歷HashMap會稍微多耗時一點,for each的結(jié)果稍微有點偏差,將測試代碼中的幾個Type順序調(diào)換會發(fā)現(xiàn),for each entrySet耗時和for iterator entrySet接近。

 

3、遍歷方式性能測試結(jié)果分析
(1) foreach介紹
見:ArrayList和LinkedList的幾種循環(huán)遍歷方式及性能對比分析中介紹。

 

(2) HashMap遍歷方式結(jié)果分析
從上面知道for each與顯示調(diào)用Iterator等價,上表的結(jié)果中可以看出除了第三種方式(for each map.keySet()),再調(diào)用get獲取方式外,其他三種方式性能相當。本例還是hash值散列較好的情況,若散列算法較差,第三種方式會更加耗時。
我們看看HashMap entrySet和keySet的源碼

Java
1
2
3
4
5
6
7
8
9
10
11
private final class KeyIterator extends HashIterator<K> {
public K next() {
return nextEntry().getKey();
}
}
private final class EntryIterator extends HashIterator<Map.Entry<K,V>> {
public Map.Entry<K,V> next() {
return nextEntry();
}
}

分別是keySet()和entrySet()返回的set的迭代器,從中我們可以看到只是返回值不同而已,父類相同,所以性能相差不多。只是第三種方式多了一步根據(jù)key get得到value的操作而已。get的時間復雜度根據(jù)hash算法而異,源碼如下:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public V get(Object key) {
if (key == null)
return getForNullKey();
Entry<K,V> entry = getEntry(key);
return null == entry ? null : entry.getValue();
}
/**
* Returns the entry associated with the specified key in the
* HashMap.  Returns null if the HashMap contains no mapping
* for the key.
*/
final Entry<K,V> getEntry(Object key) {
int hash = (key == null) ? 0 : hash(key);
for (Entry<K,V> e = table[indexFor(hash, table.length)];
e != null;
e = e.next) {
Object k;
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
return e;
}
return null;
}

get的時間復雜度取決于for循環(huán)循環(huán)次數(shù),即hash算法。

 

4、結(jié)論總結(jié)

從上面的分析來看:
a. HashMap的循環(huán),如果既需要key也需要value,直接用

Java
1
2
3
4
5
Map<String, String> map = new HashMap<String, String>();
for (Entry<String, String> entry : map.entrySet()) {
entry.getKey();
entry.getValue();
}

即可,foreach簡潔易懂。

b. 如果只是遍歷key而無需value的話,可以直接用

Java
1
2
3
4
Map<String, String> map = new HashMap<String, String>();
for (String key : map.keySet()) {
// key process
}
自己記錄并且分享給好友:


推薦一個用了一年半的理財產(chǎn)品

  • 挖財
    前阿里口碑網(wǎng) CEO 李志國創(chuàng)建了 6 年的挖財,IDG、鼎暉資本、啟明創(chuàng)投等投資。
    每月理財日 5 天 36% 年化率,17 天 8.8% 收益,28 天 7%,3 個月 9%,6 個月 10%
    邀請鏈接:看看挖財 (此鏈接注冊就送 308 元紅包券)

賬號安全:只能提現(xiàn)到資金轉(zhuǎn)入的銀行賬戶

資金安全:由平安保險全額擔保

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多