关于List的遍历、删除某一项性能比较

来源:互联网 发布:linux 日志 时间格式 编辑:程序博客网 时间:2024/05/20 07:16

一、List循环遍历性能对比

当数量很少的List,几乎任何一种循环遍历方式整体性能都无差别,但是当我们遇到数据量稍大的时候有必要考虑用哪种方式写起来比较高性能,比如我在项目中遇到遍历1000多项,不同的方法,在体验上最明显的就是界面交互时的卡顿,常见的遍历有以下三种:
第一种

for (String s : tests) {    // ....}

第二种

int size = tests.size();for (int i = 0; i < size; i++) {    tests.get(i);}

第三种

Iterator<String> it = tests.iterator();    while(it.hasNext()) {        it.next();}

多次调试表明,第二种方式在数据量较大时,遍历性能相比较其他两种最好,在界面交互上也没有了一开始的卡顿问题,因为我一开始用的方法是第一种。另外要说的是,第二种方法的循环条件,把size提前计算好,否则的话每次循环都要计算一次,也会影响性能,这个我在帮大学同学调试代码的时候遇到就是没有提前计算好,而且循环量还比较大,就导致运行报oom。

二、删除某一项

同样也是在数据量较大的时候,卡顿很明显,即使我放到了AsyncTask中,卡顿在两三秒(并不是简单的1000多项,而是项目中是树形列表的全选和取消全选功能,虽然网上有一些开源控件,但是还是决定先自己实现,因需求不同,选中效果仅仅针对本公司),我们知道,List的删除某一项可以有一下两种方法remove(int location) , remove(Object obj)
一开始我在遍历的时候,方法选择了remove(Object obj),因为觉得这样方便,

List<Model> mapList = cfMap.get(id);int size = mapList.size();for (int i = 0; i < size; i++) {    Model f = mapList.get(i);    if(selectUidMap.containsKey(f.getFid())){        selectUidMap.remove(f.getFid());        selectList.remove(f);    }}

结果就是界面交互卡顿了2-3秒,为了这个问题,纠结了好几个小时。后来没办法了,试试两层循环吧,无非代码多几行,于是改成了下面这样

List<Model > mapList = cfMap.get(id);int size = mapList.size();for (int i = 0; i < size; i++) {    Model f = mapList.get(i);    if(selectUidMap.containsKey(f.getFid())){        selectUidMap.remove(f.getFid());        int sSize = selectList.size();        for (int j = 0; j < sSize; j++) {            Model f2 = selectList.get(j);            if(f.getFid()==f2.getFid()){                selectList.remove(j);                break;            }        }    }}

结果不卡顿了,然后看了一下源码:从解释上看,
这里写图片描述

一个是将这个对象从在集合中的位置中删除,一个是删除在集合中第一次出现的符合条件的对象(内存中具体操作了什么不太清楚,是不是一个是删除引用,一个是从内存中删除,还望有知道的可以告诉我)

阅读全文
0 0