Java 中Map 根据底层数据结构的不同,存在多种不同的实现,常见如散列 HashMap ,链表linkedMap ,散列链表linkedHashMap ,树形表(二叉树) TreeMap 等。
本文讨论的是我们编程中最为常用的HashMap 散列表的 几种不同的遍历方式,及各方式间在写法和效率上的比较。
首先准备一个Map 散列表,存储十万条记录。
key 是从key0 开始一直到 key99999
value 从hello0 开始一直到 hello99999
public static void main(String[] args) {
Map<String,Object> map=new HashMap<String,Object>();
for(int i=0;i<100000;i++){
map.put("key"+i, "hello"+i);
}
}
遍历方式一 : entrySet() + 增强for循环
// Map 遍历方式一 //2425.7
static void iterator_type1(Map<String,Object> map){
Set<Map.Entry<String, Object>> set= map.entrySet();
long start=new Date().getTime();
for(Map.Entry<String, Object> item :set){
String key=item.getKey();
Object value=item.getValue();
System.out.println("key:"+key+" "+"value:"+value);
}
long end=new Date().getTime();
System.out.println("遍历耗时为:"+(end-start)+" 毫秒");
}
遍历方式二:entrySet() +iterator迭代
//Map 遍历方式二 2408.9
static void iterator_type2(Map<String,Object> map){
Set<Map.Entry<String, Object>> set= map.entrySet();
Iterator<Map.Entry<String, Object>> it= set.iterator();
long start=new Date().getTime();
while(it.hasNext()){
Map.Entry<String, Object> item= it.next();
String key=item.getKey();
Object value=item.getValue();
System.out.println("key:"+key+" "+"value:"+value);
}
long end=new Date().getTime();
System.out.println("遍历耗时为:"+(end-start)+" 毫秒");
}
遍历方式三:keySet() + iterator迭代
//Map 遍历方式三 2441.0
static void iterator_type3(Map<String,Object> map){
Set<String> keys= map.keySet();
Iterator<String> it= keys.iterator();
long start=new Date().getTime();
while(it.hasNext()){
String key=it.next();
Object value=map.get(key);
System.out.println("key:"+key+" "+"value:"+value);
}
long end=new Date().getTime();
System.out.println("遍历耗时为:"+(end-start)+" 毫秒");
}
遍历方式四:keySet() + 增强for循环
//Map 遍历方式四 2445.5
static void iterator_type4(Map<String,Object> map){
Set<String> keys= map.keySet();
long start=new Date().getTime();
for(String key :keys){
Object value=map.get(key);
System.out.println("key:"+key+" "+"value:"+value);
}
long end=new Date().getTime();
System.out.println("遍历耗时为:"+(end-start)+" 毫秒");
}
每种方式均在main函数中调用10次,统计每次遍历的耗时数据如下。
public static void main(String[] args) {
Map<String,Object> map=new HashMap<String,Object>();
for(int i=0;i<100000;i++){
map.put("key"+i, "hello"+i);
}
// iterator_type1(map);//2425.7
// iterator_type2(map); //2408.9
// iterator_type3(map); //2441.0
//iterator_type4(map);//2445.5
}
单位 毫秒
遍历方式一: 2385 2374 2357 2371 2424 2490 2528 2371 2490 2467 平均耗时 2425.7
遍历方式二: 2385 2503 2386 2334 2401 2406 2394 2414 2428 2438 平均耗时 2408.9
遍历方式三: 2391 2401 2481 2471 2423 2436 2481 2449 2414 2463 平均耗时 2441.0
遍历方式四: 2471 2392 2545 2365 2463 2465 2487 2428 2414 2425 平均耗时 2445.5
从测试的结果数据中可以看出,在以上四种遍历方式中。采用entrySet 方式 普遍比keySet方式效率高;采用entrySet中的 iterator方式又比增强for的效率高。
遍历效率最高的方式为 entrySet+iterator 方式,其次entrySet+增强for ,再次keySet+iterator,最次keySet+增强for
—-以上结论仅供参考, 纯个人测试得出的结论,并无实际的理论依据。