Java遍历Map,List的不同方法,并比较其性能

最近在做文本分析相关的实验,统计词频,情感度量许多数据预处理的工作要用到集合类的遍历,借这个机会也好好复习了一下Java中Map,List的用法。

1. Map的遍历

Map这种集合不能直接取出元素,必须要转换成Set,然后使用Iterator迭代取每一个键值对。以下方法均适用于Map的实现类HashMapHashMap,LinkedHashMap,TreeMap等

方法一:使用EntrySet(我比较常用),可以同时取出key和value

Map<String, String> testMap = new HashMap<String, String>();
Iterator<Entry<String, String>> it = testMap.entrySet().iterator();
Entry<String, String> entry = null;
while(it.hasNext()){
    entry = it.next();
    System.out.println(entry.getKey() + "\t" + entry.getValue());
}

或者使用for循环,就不需要用到Iterator

for(Map.Entry<String, String> entry: testMap.entrySet()){
    System.out.println(entry.getKey() + "\t" + entry.getValue()); 
}

方法二:使用KeySet,遍历key,然后通过map.get(key)获得对应的value

Map<String, String> testMap = new HashMap<String, String>();
String key = null;
Iterator<String> it = testMap.keySet().iterator();
while(it.hasNext()){
    key = it.next();
    //System.out.println(it.next() + "\t" + testMap.get(it.next()));
    System.out.println(key + "\t" + testMap.get(key));
}

或者使用for循环

String value = null;
for(String key : testMap.keySet()){
    value = testMap.get(key);
    System.out.println(key + "\t" + value);
}

方法三:如果只需要value,可以:
1. 使用EntrySet遍历value,同上面的方法一
2. 通过keySet遍历key,然后通过map.get(key)得到value,同上面的方法二
3. 通过values直接遍历value

Map<String, String> testMap = new HashMap<String, String>();
Iterator<String> it = testMap.values().iterator();
while(it.hasNext()){
    System.out.println(it.next());
}

或者for循环:

for(String value : testMap.values()){
    System.out.println(value);
}

遍历Map总结:
1. 如果只需要遍历key,无疑keySet最好,因为EntrySet一次性把key,value都取出来,性能上肯定开销大于只取出key。
2. 如果只想要value,遍历map.values()是最佳的选择,其他EntrySet和KeySet都要绕弯路。
3. 如果要同时取key 和value,这时EntrySet和KeySet则难分绝对优劣。我们知道HashMap是一种数组和链表结合的数据结构。在取value时,首先计算key的hashcode,然后找到数组中对应位置的某一元素,再通过key的equals方法在对应位置的链表中找到需要的元素。虽然EntrySet一次性取出key和value性能开销比只取key大,但是如果这个损失比HashMap查找value的开销小,那么EntrySet更优,否则使用KeySet,通过map.get(key)获取value。

2. List的遍历

方法一:使用普通的for循环

List<String> list = new ArrayList<String>();
for(int i = 0; i < list.size(); i++){
    System.out.println(list.get(i));
}

方法二:使用迭代器Iterator

Iterator<String> it = list.iterator();
while(it.hasNext()){
    System.out.println(it.next());
}

方法三:使用迭代器for-each

for(String str : list){
    System.out.println(str);
}

遍历ArrayList总结:
1. ArrayList的底层保存数据还是采用数组Array的方式。所以,遍历访问数组的数据,最快的方式是采用数组的索引,相当于从内存中直接读取数据。因此,使用size效率最高。但是,在多线程时需要考虑并发操作的问题。
2. for-each和Iterator实质是一样的,都是Iterator,for-each只是包装了一下,所以二者的效率是差不多的。但是,使用Iterator中会执行数据锁定,性能稍差。如果在循环过程中去掉某个元素,只能使用iterator.remove()方法,不能使用list.remove()方法,因为会出现并发访问错误。

public class CompareList {

    public static void main(String[] args) {
        List<String> list = new ArrayList<String>(); 
        long startTime = 0L, endTime = 0L;
        String temp = null;
        //赋值
        for(int k = 0; k < 1000000; k++){
            list.add("" + k);
        }

        //方法一:使用size()方法
        startTime = System.currentTimeMillis();
        for(int i=0;i<list.size();i++) {  
            temp = list.get(i);
            //System.out.println(temp);
        }
        endTime = System.currentTimeMillis();
        System.out.println("使用size,时间为: " + (endTime - startTime) + "mm");

        //方法二:使用Iterator
        Iterator<String> it = list.iterator();
        startTime = System.currentTimeMillis();  
        while(it.hasNext()){
            temp = it.next();
            //System.out.println(temp);
        }
        endTime = System.currentTimeMillis();  
        System.out.println("使用Iterator,时间为:"+ (endTime - startTime) + "mm");

        //方法三:使用for-each
        startTime = System.currentTimeMillis();  
        for(String s : list) {  
            temp = s;
            //System.out.println(temp);
        }  
        endTime = System.currentTimeMillis();  
        System.out.println("使用for-each,时间为:"+ (endTime - startTime) + "mm");  

    }

}

实验结果:
使用size,时间为: 12mm
使用Iterator,时间为:14mm
使用for-each,时间为:22mm

多次重复实验,基本都在一个数量级,但是每次都是size最好。

总结的可能不够好,实验也许不科学,欢迎批评指教!

    原文作者:小白沉淀
    原文地址: https://blog.csdn.net/anecdotegyb/article/details/63255129
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞