Java Map遍歷方式方式及性能測試
1. 闡述
對于Java中Map的遍歷方式,很多文章都推薦使用entrySet,認為其比keySet的效率高很多。理由是:entrySet方法一次拿到所有key和value的集合;而keySet拿到的只是key的集合,針對每個key,都要去Map中額外查找一次value,從而降低了總體效率。那么實際情況如何呢?
為了解遍歷性能的真實差距,包括在遍歷key+value、遍歷key、遍歷value等不同場景下的差異,我試著進行了一些對比測試。
2. 對比測試
一開始只進行了簡單的測試,但結果卻表明keySet的性能更好,這一點讓我很是費解,不都說entrySet明顯好于keySet嗎?為了進一步地進行驗證,于是采用了不同的測試數據進行更詳細的對比測試。
2.1 測試數據
2.1.1 HashMap測試數據
HashMap-1,大小為100萬,key和value均為String,key的值為1、2、3……1000000:
Map<String, String> map = new HashMap<String, String>();
String key, value;
for (i = 1; i <= num; i++) {
key = "" + i;
value = "value";
map.put(key, value);
} HashMap-2,大小為100萬,key和value均為String,key的值為50、100、150、200、……、50000000:
Map<String, String> map = new HashMap<String, String>();
String key, value;
for (i = 1; i <= num; i++) {
key = "" + (i * 50);
value = "value";
map.put(key, value);
} 2.1.2 TreeMap測試數據
TreeMap-1,大小為100萬,key和value均為String,key的值為1、2、3……1000000:
Map<String, String> map = new TreeMap<String, String>();
String key, value;
for (i = 1; i <= num; i++) {
key = "" + i;
value = "value";
map.put(key, value);
} TreeMap-2,大小為100萬,key和value均為String,key的值為50、100、150、200、……、50000000,更離散:
Map<String, String> map = new TreeMap<String, String>();
String key, value;
for (i = 1; i <= num; i++) {
key = "" + (i * 50);
value = "value";
map.put(key, value);
} 2.2 測試場景
分別使用keySet、entrySet和values的多種寫法測試三種場景:遍歷key+value、遍歷key、遍歷value的場景。
2.2.1 遍歷key+value
keySet遍歷key+value(寫法1):
Iterator<String> iter = map.keySet().iterator();
while (iter.hasNext()) {
key = iter.next();
value = map.get(key);
} keySet遍歷key+value(寫法2):
for (String key : map.keySet()) {
value = map.get(key);
} entrySet遍歷key+value(寫法1):
Iterator<Entry<String, String>> iter = map.entrySet().iterator();
Entry<String, String> entry;
while (iter.hasNext()) {
entry = iter.next();
key = entry.getKey();
value = entry.getValue();
} entrySet遍歷key+value(寫法2):
for (Entry<String, String> entry: map.entrySet()) {
key = entry.getKey();
value = entry.getValue();
} 2.2.2 遍歷key
keySet遍歷key(寫法1):
Iterator<String> iter = map.keySet().iterator();
while (iter.hasNext()) {
key = iter.next();
} keySet遍歷key(寫法2):
for (String key : map.keySet()) {
} entrySet遍歷key(寫法1):
Iterator<Entry<String, String>> iter = map.entrySet().iterator();
while (iter.hasNext()) {
key = iter.next().getKey();
} entrySet遍歷key(寫法2):
for (Entry<String, String> entry: map.entrySet()) {
key = entry.getKey();
} 2.2.3 遍歷value
keySet遍歷value(寫法1):
Iterator<String> iter = map.keySet().iterator();
while (iter.hasNext()) {
value = map.get(iter.next());
} keySet遍歷value(寫法2):
for (String key : map.keySet()) {
value = map.get(key);
} entrySet遍歷value(寫法1):
Iterator<Entry<String, String>> iter = map.entrySet().iterator();
while (iter.hasNext()) {
value = iter.next().getValue();
} entrySet遍歷value(寫法2):
for (Entry<String, String> entry: map.entrySet()) {
value = entry.getValue();
} values遍歷value(寫法1):
Iterator<String> iter = map.values().iterator();
while (iter.hasNext()) {
value = iter.next();
} values遍歷value(寫法2):
for (String value : map.values()) {
}2.3 測試結果
2.3.1 HashMap測試結果
|
單位:毫秒 </td> |
HashMap-1 </td> |
HashMap-2 </td> </tr> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| keySet遍歷key+value(寫法1) |
39 </td> |
93 </td> </tr> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| keySet遍歷key+value(寫法2) |
38 </td> |
87 </td> </tr> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| entrySet遍歷key+value(寫法1) |
43 </td> |
86 </td> </tr> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| entrySet遍歷key+value(寫法2) |
43 </td> |
85 </td> </tr> </tbody> </table> </div>
|