ITPub博客

首页 > IT职业 > IT生活 > 将List按照指定大小等分的几种实现方式和效率对比及优化

将List按照指定大小等分的几种实现方式和效率对比及优化

IT生活 作者:lzg215 时间:2021-09-09 09:30:08 0 删除 编辑

写在前面

    今天碰到一个需求,定时任务,批量从表里取数据并做一些其他操作然后再存表,每次取1000条,由于计算过程比较耗时所以要起多个线程同时跑,需要将List按照指定大小等分,如每100条数据起一个线程,若最后剩余一份不到100,也放到一个线程里,网络上的实现方法有很多,我测试之后理出三种相对比较好的实现方法,如下:

/*第一种方法 思路比较简单,遍历list,将元素添加到subList,
*每当i到pageSize的时候,将subList添加到listArray并新建,subList
*/
public static  List> splitList1(List list, int pageSize) {

    List> listArray = new ArrayList>();

    List subList = null;

    for (int i = 0; i ();

            listArray.add(subList);

        }

        subList.add(list.get(i));

    }

    return listArray;

}
/*第二种方法 思路和方法1差不多,遍历list,将元素添加到subList,
*当subList的size等于pageSize的时候,将subList添加到listArray并新建subList
*/
public static  List> splitList2(List list, int pageSize) {

    List> listArray = new ArrayList>();

    ArrayList subList = new ArrayList();
    for (T x : list) {
        subList.add(x);
        if (pageSize == subList.size()) {
            listArray.add(subList);
            subList = new ArrayList();
        }
    }

    if (0 != subList.size()) {
        listArray.add(subList);
    }

    return listArray;
}
/*第三种方法,用到了java list自带的方法subList,
*先判断list的size<pageSize的情况,然后利用subList方法循环切块
*/
public static  List> splitList3(List list, int pageSize) {
    List> listArray = new ArrayList>();
    if (list != null && pageSize > 0) {
        int listSize = list.size();
        if (listSize  0) {
            listArray.add(list.subList(listSize - remain, listSize));
        }
    }
    return listArray;
}

    我从list的subList方法中得到灵感,也实现了一种方式,可读性稍好一些,如下:

/*我的思路也比较简单,就是遍历加切块,
*若toIndex大于list的size说明已越界,需要将toIndex设为list的size值
*/
public static  List> splitList4(List list, int pageSize) {
    List> listArray = new ArrayList>();
    for (int i = 0; i list.size()?list.size():i+pageSize;
        listArray.add(list.subList(i, toIndex));
    }
    return listArray;
}

    以上四种方法经过测试都可实现功能,如果List的size比较小,几十,几百,应该效率都差不多,那如果list的size很大,比如10万,100万,那么以上四种方式,哪一种效率最高呢,我简单测试了一下,pageSize设为20,list的size分别为10万,和100万,分别跑100次,然后取平均值,如下:

public static void main(String[] args) {
    ArrayList list = new ArrayList();

    for (int i = 0; i :" + (time2 - time1)/100.0+"ms");
    System.out.println("方法2--->:" + (time3 - time2)/100.0+"ms");
    System.out.println("方法3--->:" + (time4 - time3)/100.0+"ms");
    System.out.println("方法4--->:" + (time5 - time4)/100.0+"ms");


}

执行结果为

ist的size为100000,执行100次,平均时间为:
方法1--->:2.86ms
方法2--->:2.08ms
方法3--->:0.66ms
方法4--->:0.43ms

    从执行结果中可以看到前两种方法效率,明显不如后两种,后两种时间相差不大,但看起来似乎方法4更好一些,再将list的size设为100万时,执行结果为:

list的size为1000000,执行100次,平均时间为:
方法1--->:21.65ms
方法2--->:14.09ms
方法3--->:0.95ms
方法4--->:0.57ms

    size设为1000万时,执行结果为:

list的size为1000000,执行100次,平均时间为:
方法1--->:138.39ms
方法2--->:112.86ms
方法3--->:6.63ms
方法4--->:6.07ms

    综上所看,方法4的效率稍好于方法3,方法2稍好于方法1,但3和4的效率比1和2要高出一个数量级,主要是因为方法1和2,是逐个设置的,很明显不如subList,在这里推荐方法4,代码简洁,稍微理解下,可读性也不错.

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/420/viewspace-2803908/ ,如需转载,请注明出处,否则将追究法律责任。

上一篇: 索引的基本操作
请登录后发表评论 登录
全部评论

注册时间:2020-07-23

  • 博文量
    0
  • 访问量
    754