對於j**a中map的遍歷方式,很多文章都推薦使用entryset,認為其比keyset的效率高很多。理由是:entryset方法一次拿到所有key和value的集合;而keyset拿到的只是key的集合,針對每個key,都要去map中額外查詢一次value,從而降低了總體效率。那麼實際情況如何呢?
為了解遍歷性能的真實差距,包括在遍歷key+value、遍歷key、遍歷value等不同場景下的差異,我試著進行了一些對比測試。
一開始只進行了簡單的測試,但結果卻表明keyset的效能更好,這一點讓我很是費解,不都說entryset明顯好於keyset嗎?為了進一步地進行驗證,於是採用了不同的測試資料進行更詳細的對比測試。
mapmap = new hashmap();
string key, value;
for (i = 1; i <= num; i++)
mapmap = new hashmap();
string key, value;
for (i = 1; i <= num; i++)
2.1.2 treemap測試資料
mapmap = new treemap();
string key, value;
for (i = 1; i <= num; i++)
mapmap = new treemap();
string key, value;
for (i = 1; i <= num; i++)
2.2 測試場景
分別使用keyset、entryset和values的多種寫法測試三種場景:遍歷key+value、遍歷key、遍歷value的場景。
iteratoriter = map.keyset().iterator();
while (iter.hasnext())
for (string key : map.keyset())
iterator> iter = map.entryset().iterator();
entryentry;
while (iter.hasnext())
for (entryentry: map.entryset())
iteratoriter = map.keyset().iterator();
while (iter.hasnext())
for (string key : map.keyset())
iterator> iter = map.entryset().iterator();
while (iter.hasnext())
for (entryentry: map.entryset())
2.2.3 遍歷value
iteratoriter = map.keyset().iterator();
while (iter.hasnext())
for (string key : map.keyset())
iterator> iter = map.entryset().iterator();
while (iter.hasnext())
for (entryentry: map.entryset())
iteratoriter = map.values().iterator();
while (iter.hasnext())
for (string value : map.values())
2.3 測試結果
單位:毫秒
hashmap-1
hashmap-2
keyset遍歷key+value(寫法1)
3993
keyset遍歷key+value(寫法2)
3887
entryset遍歷key+value(寫法1)
4386
entryset遍歷key+value(寫法2)
4385
單位:毫秒
hashmap-1
hashmap-2
keyset遍歷key(寫法1)
2765
keyset遍歷key(寫法2)
2664
entryset遍歷key(寫法1)
3575
entryset遍歷key(寫法2)
3474
單位:毫秒
hashmap-1
hashmap-2
keyset遍歷value(寫法1)
3887
keyset遍歷value(寫法2)
3787
entryset遍歷value(寫法1)
3461
entryset遍歷value(寫法2)
3262
values遍歷value(寫法1)
2648
values遍歷value(寫法2)
2648
2.3.2 treemap測試結果
單位:毫秒
treemap-1
treemap-2
keyset遍歷key+value(寫法1)
430451
keyset遍歷key+value(寫法2)
429450
entryset遍歷key+value(寫法1)
7784
entryset遍歷key+value(寫法2)
7068
單位:毫秒
treemap-1
treemap-2
keyset遍歷key(寫法1)
5049
keyset遍歷key(寫法2)
4948
entryset遍歷key(寫法1)
6664
entryset遍歷key(寫法2)
6563
單位:毫秒
treemap-1
treemap-2
keyset遍歷value(寫法1)
432448
keyset遍歷value(寫法2)
430448
entryset遍歷value(寫法1)
6261
entryset遍歷value(寫法2)
6261
values遍歷value(寫法1)
4646
values遍歷value(寫法2)
4546
3. 結論
同時遍歷key和value時,keyset與entryset方法的效能差異取決於key的具體情況,如複雜度(複雜物件)、離散度、衝突率等。換言之,取決於hashmap查詢value的開銷。entryset一次性取出所有key和value的操作是有效能開銷的,當這個損失小於hashmap查詢value的開銷時,entryset的效能優勢就會體現出來。例如上述對比測試中,當key是最簡單的數值字串時,keyset可能反而會更高效,耗時比entryset少10%。總體來說還是推薦使用entryset。因為當key很簡單時,其效能或許會略低於keyset,但卻是可控的;而隨著key的複雜化,entryset的優勢將會明顯體現出來。當然,我們可以根據實際情況進行選擇
只遍歷key時,keyset方法更為合適,因為entryset將無用的value也給取出來了,浪費了效能和空間。在上述測試結果中,keyset比entryset方法耗時少23%。
只遍歷value時,使用vlaues方法是最佳選擇,entryset會略好於keyset方法。
for (string key : map.keyset())
for (entryentry: map.entryset())
for (string value : map.values())
3.2 如果你使用treemap
同時遍歷key和value時,與hashmap不同,entryset的效能遠遠高於keyset。這是由treemap的查詢效率決定的,也就是說,treemap查詢value的開銷較大,明顯高於entryset一次性取出所有key和value的開銷。因此,遍歷treemap時強烈推薦使用entryset方法。
只遍歷key時,keyset方法更為合適,因為entryset將無用的value也給取出來了,浪費了效能和空間。在上述測試結果中,keyset比entryset方法耗時少24%。
只遍歷value時,使用vlaues方法是最佳選擇,entryset也明顯優於keyset方法。
for (string key : map.keyset())
for (entryentry: map.entryset())
for (string value : map.values())
Java中遍歷乙個Map的方法
mapmap new hashmap map.put a a map.put b b map.put c c 第一種 set set map.keyset iterator it set.iterator while it.hasnext 第二種 set entryset map.entryset ...
如何將乙個類的屬性轉換成乙個MAP
需求 如何將乙個類轉換成乙個map,同時針對類中的屬性有要求,date型別 需要變成string,yyyy mm dd hh mm ss 物件需要變成json。如何寫乙個通用的工具 下面是具體的實現方式 string value object object override public strin...
map裡面再巢狀乙個map 二級map
例子 首先定義乙個二級 mapstr 然後將 list 裡的值賦值到 map 裡面.map mapstr listl fruits l fruits.push back banana l fruits.push back orange l fruits.push back grape l fruit...