將List按照指定大小等分的幾種實現方式和效率對比及優化

  今天碰到一個需求,定時任務,批量從表裏取數據並作一些其餘操做而後再存表,每次取1000條,因爲計算過程比較耗時因此要起多個線程同時跑,須要將List按照指定大小等分,如每100條數據起一個線程,若最後剩餘一份不到100,也放到一個線程裏,網絡上的實現方法有不少,我測試以後理出三種相對比較好的實現方法,以下:java

 1 /*第一種方法 思路比較簡單,遍歷list,將元素添加到subList,
 2 *每當i到pageSize的時候,將subList添加到listArray並新建,subList
 3 */
 4 public static <T> List<List<T>> splitList1(List<T> list, int pageSize) {
 5  
 6     List<List<T>> listArray = new ArrayList<List<T>>();
 7  
 8     List<T> subList = null;
 9  
10     for (int i = 0; i < list.size(); i++) {
11  
12         if (i % pageSize == 0) {
13  
14             subList = new ArrayList<T>();
15  
16             listArray.add(subList);
17  
18         }
19  
20         subList.add(list.get(i));
21  
22     }
23  
24     return listArray;
25  
26 }
/*第二種方法 思路和方法1差很少,遍歷list,將元素添加到subList,
*當subList的size等於pageSize的時候,將subList添加到listArray並新建subList
*/
public static <T> List<List<T>> splitList2(List<T> list, int pageSize) {
 
    List<List<T>> listArray = new ArrayList<List<T>>();
 
    ArrayList<T> subList = new ArrayList<T>();
    for (T x : list) {
        subList.add(x);
        if (pageSize == subList.size()) {
            listArray.add(subList);
            subList = new ArrayList<T>();
        }
    }
 
    if (0 != subList.size()) {
        listArray.add(subList);
    }
 
    return listArray;
}
/*第三種方法,用到了java list自帶的方法subList,
*先判斷list的size<pageSize的狀況,而後利用subList方法循環切塊
*/
public static <T> List<List<T>> splitList3(List<T> list, int pageSize) {
    List<List<T>> listArray = new ArrayList<List<T>>();
    if (list != null && pageSize > 0) {
        int listSize = list.size();
        if (listSize <= pageSize) {
            listArray.add(list);
            return listArray;
        }
        int batchSize = listSize / pageSize;
        int remain = listSize % pageSize;
 
        for (int i = 0; i < batchSize; i++) {
            int fromIndex = i * pageSize;
            int toIndex = fromIndex + pageSize;
            listArray.add(list.subList(fromIndex, toIndex));
        }
        if (remain > 0) {
            listArray.add(list.subList(listSize - remain, listSize));
        }
    }
    return listArray;
}

  我從list的subList方法中獲得靈感,也實現了一種方式,可讀性稍好一些,以下:網絡

/*個人思路也比較簡單,就是遍歷加切塊,
*若toIndex大於list的size說明已越界,須要將toIndex設爲list的size值
*/
public static <T> List<List<T>> splitList4(List<T> list, int pageSize) {
    List<List<T>> listArray = new ArrayList<List<T>>();
    for (int i = 0; i < list.size(); i+=pageSize) {
        int toIndex = i + pageSize>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<Integer> list = new ArrayList<Integer>();
 
    for (int i = 0; i < 100000; i++) {
        list.add(i);
    }
 
    Long time1 = System.currentTimeMillis();
    for (int i = 0; i <100 ; i++) {
        splitList1(list, 20);
    }
    Long time2 = System.currentTimeMillis();
    for (int i = 0; i <100 ; i++) {
        splitList2(list, 20);
    }
    Long time3 = System.currentTimeMillis();
    for (int i = 0; i <100 ; i++) {
        splitList3(list, 20);
    }
    Long time4 = System.currentTimeMillis();
    for (int i = 0; i <100 ; i++) {
        splitList3(list, 20);
    }
    Long time5 = System.currentTimeMillis();
 
 
    System.out.println("list的size爲10000,執行100次,平均時間爲:");
    System.out.println("方法1--->:" + (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");
 
 
}

  執行結果爲:spa

list的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萬時,執行結果爲:code

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,代碼簡潔,稍微理解下,可讀性也不錯.blog


 

 

 

原文連接:https://www.imooc.com/article/41647
來源:慕課網
本文原創發佈於慕課網 ,轉載請註明出處,謝謝合做rem

相關文章
相關標籤/搜索