最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java?list和map切割分段的實(shí)現(xiàn)及多線程應(yīng)用案例

 更新時(shí)間:2023年12月24日 15:08:04   作者:蠶1蠶2  
這篇文章主要為大家介紹了java?list和map切割分段的實(shí)現(xiàn)及多線程應(yīng)用案例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

map工具類

/**
 * @author chengxianwei
 * @title map工具類
 * @date 2023/08/03
 **/
public class MapUtil {
    /**
     * List拆分 (指定分組大小)
     *
     * @param chunkList 被分隔的數(shù)組
     * @param chunkNum  每段的大小
     * @param <T>       List中的類型
     * @return
     */
    public static <T> List<List<T>> listChunk(List<T> chunkList, int chunkNum) {
        if (chunkList == null || chunkNum <= 0) {
            List<List<T>> t = new ArrayList<>();
            t.add(chunkList);
            return t;
        }
        Iterator<T> iterator = chunkList.iterator();
        int i = 1;
        List<List<T>> total = new ArrayList<>();
        List<T> tem = new ArrayList<>();
        while (iterator.hasNext()) {
            T next = iterator.next();
            tem.add(next);
            if (i == chunkNum) {
                total.add(tem);
                tem = new ArrayList<>();
                i = 0;
            }
            i++;
        }
        if (!ChargeEmptyUtil.isEmpty(tem)) {
            total.add(tem);
        }
        return total;
    }
    /**
     * Map拆分 (指定分組大小)
     *
     * @param chunkMap 被切段的map
     * @param chunkNum 每段的大小
     * @param <k>      map的key類型
     * @param <v>      map的value類型 如果是自定義類型,則必須實(shí)現(xiàn)equals和hashCode方法
     * @return
     */
    public static <k, v> List<Map<k, v>> mapChunk(Map<k, v> chunkMap, int chunkNum) {
        if (chunkMap == null || chunkNum <= 0) {
            List<Map<k, v>> list = new ArrayList<>();
            list.add(chunkMap);
            return list;
        }
        Set<k> keySet = chunkMap.keySet();
        Iterator<k> iterator = keySet.iterator();
        int i = 1;
        List<Map<k, v>> total = new ArrayList<>();
        Map<k, v> tem = new HashMap<>();
        while (iterator.hasNext()) {
            k next = iterator.next();
            tem.put(next, chunkMap.get(next));
            if (i == chunkNum) {
                total.add(tem);
                tem = new HashMap<>();
                i = 0;
            }
            i++;
        }
        if (!ChargeEmptyUtil.isEmpty(tem)) {
            total.add(tem);
        }
        return total;
    }
    /**
     * Map拆分 (指定分組大小)
     *
     * @param map       Map
     * @param chunkSize 每個(gè)分組的大小 (>=1)
     * @param <K>       Key
     * @param <V>       Value
     * @return 子Map列表
     */
    public static <K, V> List<Map<K, V>> splitByChunkSize(Map<K, V> map, int chunkSize) {
        if (Objects.isNull(map) || map.isEmpty() || chunkSize < 1) {
            //空map或者分組大小<1,無法拆分
            return Collections.emptyList();
        }
        int mapSize = map.size(); //鍵值對總數(shù)
        int groupSize = mapSize / chunkSize + (mapSize % chunkSize == 0 ? 0 : 1); //計(jì)算分組個(gè)數(shù)
        List<Map<K, V>> list = Lists.newArrayListWithCapacity(groupSize); //子Map列表
        if (chunkSize >= mapSize) { //只能分1組的情況
            list.add(map);
            return list;
        }
        int count = 0; //每個(gè)分組的組內(nèi)計(jì)數(shù)
        Map<K, V> subMap = Maps.newHashMapWithExpectedSize(chunkSize); //子Map
        for (Map.Entry<K, V> entry : map.entrySet()) {
            if (count < chunkSize) {
                //給每個(gè)分組放chunkSize個(gè)鍵值對,最后一個(gè)分組可能會裝不滿
                subMap.put(entry.getKey(), entry.getValue());
                count++; //組內(nèi)計(jì)數(shù)+1
            } else {
                //結(jié)束上一個(gè)分組
                list.add(subMap); //當(dāng)前分組裝滿了->加入列表
                //開始下一個(gè)分組
                subMap = Maps.newHashMapWithExpectedSize(chunkSize); //新的分組
                subMap.put(entry.getKey(), entry.getValue()); //添加當(dāng)前鍵值對
                count = 1; //組內(nèi)計(jì)數(shù)重置為1
            }
        }
        list.add(subMap);  //添加最后一個(gè)分組
        return list;
    }
    /**
     * Map拆分(指定分組個(gè)數(shù))
     *
     * @param map       Map
     * @param groupSize 分組個(gè)數(shù) (>=1)
     * @param <K>       Key
     * @param <V>       Value
     * @return 子Map列表
     */
    public static <K, V> List<Map<K, V>> splitByGroupSize(Map<K, V> map, int groupSize) {
        if (Objects.isNull(map) || map.isEmpty() || groupSize < 1) {
            //空map或者分組數(shù)<1,無法拆分
            return Collections.emptyList();
        }
        List<Map<K, V>> list = Lists.newArrayListWithCapacity(groupSize);
        if (groupSize == 1) { //只有1個(gè)分組的情況
            list.add(map);
            return list;
        }
        int mapSize = map.size(); //鍵值對總數(shù)
        int chunkIndex = 0; //當(dāng)前分組的下標(biāo),[0, groupSize-1]
        int restCount = mapSize % groupSize; //平均后剩余的鍵值對數(shù)
        int chunkSize0 = mapSize / groupSize; //每個(gè)分組鍵值對數(shù)量
        int chunkSize1 = chunkSize0 + 1; //多分一個(gè)
        int chunkSize = chunkIndex < restCount ? chunkSize1 : chunkSize0; //實(shí)際每組的大小(前面的部分分組可能會多分1個(gè))
        int count = 0; //每個(gè)分組的組內(nèi)計(jì)數(shù)
        Map<K, V> subMap = Maps.newHashMapWithExpectedSize(chunkSize);//子Map
        for (Map.Entry<K, V> entry : map.entrySet()) {
            if (count < chunkSize) {
                //每個(gè)分組按實(shí)際分組大?。╟hunkSize)加入鍵值對
                subMap.put(entry.getKey(), entry.getValue());
                count++; //組內(nèi)計(jì)數(shù)+1
            } else {
                //結(jié)束上一個(gè)分組
                list.add(subMap); //當(dāng)前分組裝滿了->加入列表
                chunkIndex++; //分組個(gè)數(shù)+1
                //開始下一個(gè)分組
                chunkSize = chunkIndex < restCount ? chunkSize1 : chunkSize0; //重新計(jì)算分組大小
                subMap = Maps.newHashMapWithExpectedSize(chunkSize); //新的分組
                subMap.put(entry.getKey(), entry.getValue()); //添加當(dāng)前鍵值對
                count = 1; //組內(nèi)計(jì)數(shù)重置為1
            }
        }
        list.add(subMap); //添加最后一個(gè)分組
        return list;
    }
    //測試
    public static void main(String[] args) {
        Map<String, String> map = new HashMap<>();
        map.put("a", "1");
        map.put("b", "2");
        map.put("c", "3");
        map.put("d", "4");
        map.put("e", "5");
        map.put("f", "6");
        map.put("g", "7");
        System.out.println("splitByChunkSize: " + splitByChunkSize(map, 3));
        System.out.println("splitByGroupSize: " + splitByGroupSize(map, 3));
    }
}

應(yīng)用案例

List分段

{
            // 導(dǎo)出動態(tài)標(biāo)題
            List<String> titleList = new ArrayList<>();
            // 上網(wǎng)電量和發(fā)電量
            String[] monthKeyArr = {"powernetday", "powerday"};
            // 獲取導(dǎo)出電站基礎(chǔ)數(shù)據(jù)
            List<XczxPoverPhotovolSourceVO>[0] = new ArrayList<>();
            // 保存成<consNo, <日電量數(shù)據(jù)列表>> 形式
            ConcurrentHashMap<String, List<XczxPoverPhotovolSourceDayEleVO>> xczxPovertyPowerDayListMap = new ConcurrentHashMap<>();
            ...
            ...
            ...
            // 多線程分段批量處理List列表
            int threadSize = 2000;//每2000條開啟一個(gè)任務(wù)
            int dataSize = xczxPoverPhotovolSourceVOList[0].size();
            int threadNum = dataSize / threadSize + 1;// 開啟的任務(wù)數(shù)
            boolean special = dataSize % threadSize ==0;// 表計(jì)整除 (threadNum多算了一次)
            Callable<Integer> task = null;
            List<XczxPoverPhotovolSourceVO> curList = null;
            List<Callable<Integer>> tasks = new ArrayList<>();
            ExecutorService exec = Executors.newCachedThreadPool();
            CountDownLatch countDownLatch = new CountDownLatch(threadNum);
            // 使用Collections將線程不安全的集合轉(zhuǎn)成線程安全的集合
            List<Map<String, Object>> dataList = Collections.synchronizedList(new ArrayList<>(dataSize));
            for (int i = 0; i < threadNum; i++) {
                if (i == threadNum - 1) {
                    if(special){
                        countDownLatch.countDown();
                        break;
                    }
                    curList = xczxPoverPhotovolSourceVOList[0].subList(threadSize * i, dataSize);
                } else {
                    curList = xczxPoverPhotovolSourceVOList[0].subList(threadSize * i, threadSize * (i + 1));
                }
                final List<XczxPoverPhotovolSourceVO> list2 = curList;
                task = new Callable<Integer>() {
                    @Override
                    public synchronized Integer call() throws Exception {
                        try {
                            XczxPoverPhotovolSourceVO next = null;
                            Date parallelInTime = null;
                            Map<String, Object> map = null;
                            List<Map<String, Object>> totalList = null;
                            Map<String, Object> totalMap = null;
                            List<Map<String, Object>> povertyList = null;
                            Map<String, Object> entityMap = null;
                            XczxPoverPhotovolSourceDayEleVO next2 = null;
                            XczxPoverPhotovolSourceDayEleVO curDayEle = null;
                            List<XczxPoverPhotovolSourceDayEleVO> list = null;
                            List<XczxPoverPhotovolSourceDayEleVO> listDay = new ArrayList<>();
                            // 迭代導(dǎo)出電站基礎(chǔ)數(shù)據(jù)
                            Iterator<XczxPoverPhotovolSourceVO> iterator = list2.iterator();
                            while (iterator.hasNext()) {
                                next = iterator.next();
                                map = CommonUtils.transClassToMapLowCase(next);
                                // 合計(jì) 集合
                                totalList = new ArrayList<>();
                                totalMap = new HashMap<>();
                                // 合計(jì)
                                BigDecimal powerNetTotal = new BigDecimal(BigInteger.ZERO);
                                BigDecimal powerTotal = new BigDecimal(BigInteger.ZERO);
                                // 指定日期的 戶號列表 17123
                                listDay = xczxPovertyPowerDayListMap.get(""+next.getId());
                                if (listDay != null && listDay.size() > 0) {
                                    // 遍歷一個(gè)戶號 所有日期
                                    for (int i = 0; i < titleList.size() - 1; i++) {
                                        String date = titleList.get(i).substring(0, 4) + titleList.get(i).substring(5, 7) + titleList.get(i).substring(8, 10);
                                        list = listDay.stream().filter(x -> date.equals(x.getPovertyDay())).collect(Collectors.toList());
                                        povertyList = new ArrayList<>();
                                        entityMap = new HashMap<>();
                                        if (list != null && list.size() > 0) {
                                            for (XczxPoverPhotovolSourceDayEleVO vo : list) {
                                                entityMap.put(monthKeyArr[0] + titleList.get(i), new BigDecimal(vo.getPowerNetDay()));
                                                entityMap.put(monthKeyArr[1] + titleList.get(i), new BigDecimal(vo.getPowerDay()));
                                                powerNetTotal = powerNetTotal.add(new BigDecimal(vo.getPowerNetDay()));
                                                powerTotal = powerTotal.add(new BigDecimal(vo.getPowerDay()));
                                                povertyList.add(entityMap);
                                            }
                                        } else {
                                            // 如果為空,填充0
                                            entityMap.put(monthKeyArr[0] + titleList.get(i), "0");
                                            entityMap.put(monthKeyArr[1] + titleList.get(i), "0");
                                            povertyList.add(entityMap);
                                        }
                                        map.put(day + titleList.get(i), povertyList);
                                    }
                                } else {
                                    // 遍歷一個(gè)戶號 所有日期
                                    for (int i = 0; i < titleList.size() - 1; i++) {
                                        povertyList = new ArrayList<>();
                                        entityMap = new HashMap<>();
                                        // 如果為空,填充0
                                        entityMap.put(monthKeyArr[0] + titleList.get(i), "0");
                                        entityMap.put(monthKeyArr[1] + titleList.get(i), "0");
                                        povertyList.add(entityMap);
                                        povertyList.add(entityMap);
                                        map.put(day + titleList.get(i), povertyList);
                                    }
                                }
                                // 合計(jì)模型
                                totalMap.put(monthKeyArr[0] + "合計(jì)", powerNetTotal);
                                totalMap.put(monthKeyArr[1] + "合計(jì)", powerTotal);
                                totalList.add(totalMap);
                                map.put(day + "合計(jì)", totalList);
                                dataList.add(map);
                                map.put("xh", dataList.size());
                            }
                        } catch (Exception e) {
                            log.error("catch error",e);
                        } finally {
                            countDownLatch.countDown();
                            return 1;
                        }
                    }
                };
                tasks.add(task);
            }
            // 多線程并發(fā)
            List<Future<Integer>> futureList = null;
            try {
                futureList = exec.invokeAll(tasks);
                for(Future<Integer> future : futureList){
                    if(future!=null) {
                        while (!future.isDone());
                    }
                }
                countDownLatch.await();
            } catch (Exception e) {
                log.error("catch error",e);
            } finally {
                exec.shutdown();
            }
            ...
            ...
            ...
}

Map分段

{
           ...
           ...
           ...
           // <戶主身份證號, List<戶主成員(含戶主)>> 集合檔案信息
           Map<String, List<XczxArchives>> impListMap = new HashMap<>();
           ...
           ...
           ...
           // 多線程分段批量處理Map集合
           int threadSize = 2000;// 每2000條開啟一個(gè)任務(wù)
           int dataSize = impListMap.size();// map數(shù)據(jù)條數(shù)
           int threadNum = dataSize / threadSize + 1;// 開啟的任務(wù)數(shù)
           List<Callable<Integer>> tasks = new ArrayList<>();
           ExecutorService exec = Executors.newCachedThreadPool();
           List<Map<String, List<XczxArchives>>> splitGroup = MapUtil.splitByChunkSize(impListMap, threadSize);
           for (int i = 0; i < threadNum; i++) {
               Map<String, List<XczxArchives>> curLists = splitGroup.get(i);
               // 新建一個(gè)并發(fā)任務(wù)
               Callable<Integer> task = new Callable<Integer>() {
                   @Override
                   public Integer call() throws Exception {
                       int count = 0;
                       // iterator遍歷分段Map
                       Iterator<Map.Entry<String, List<XczxArchives>>> entryIterator = curLists.entrySet().iterator();
                       while (entryIterator.hasNext()) {
                           XczxArchives head = null;
                           Map.Entry<String, List<XczxArchives>> entry = entryIterator.next();
                           String key = entry.getKey();// 戶主身份證號
                           List<XczxArchives> list = entry.getValue();// 戶主及成員列表
                           Iterator<XczxArchives> dataIterator = list.iterator();
                           while (dataIterator.hasNext()) {
                               XczxArchives next = dataIterator.next();
                               if (key.equals(next.getIdCard())) {
                                   head = next;
                                   dataIterator.remove();
                               }
                           }
                           if (head != null) {
                               // 插入戶主
                               head.setHeadName(null);
                               head.setHeadIdCard(null);
                               head.setHeadMobile(null);
                               head.setCreateTime(date);
                               head.setUpdateTime(date);
                               int result = xczxArchivesMapper.insert(head);
                               if (result == 1) {
                                   count++;
                                   if (list != null && list.size() > 0) {
                                       for (XczxArchives next : list) {
                                           next.setCreateTime(date);
                                           next.setUpdateTime(date);
                                           next.setHeadId(head.getArchivesId());
                                       }
                                       // 插入成員
                                       int result2 = xczxArchivesMapper.batchInsert(list);
                                       if (result2 > 0) {
                                           count = count + result2;
                                       }
                                   }
                               }
                           }
                       }
                       return count;
                   }
               };
               tasks.add(task);
           }
           // 多線程并發(fā)
           List<Future<Integer>> futureList = null;
           try {
               futureList = exec.invokeAll(tasks);
               for (Future<Integer> future : futureList) {
                   if (future != null) {
                       while (!future.isDone());
                       successCount = successCount + future.get();
                   }
               }
           } catch (Exception e) {
               log.error("catch error",e);
           } finally {
               exec.shutdown();
           }
           ...
           ...
           ...
}

以上就是java list和map切割分段的實(shí)現(xiàn)及多線程應(yīng)用案例的詳細(xì)內(nèi)容,更多關(guān)于java list map多線程切割分段的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java對象轉(zhuǎn)json JsonFormat注解

    Java對象轉(zhuǎn)json JsonFormat注解

    這篇文章主要介紹了Java對象轉(zhuǎn)json JsonFormat注解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-05-05
  • 使用Java自定義注解實(shí)現(xiàn)一個(gè)簡單的令牌桶限流器

    使用Java自定義注解實(shí)現(xiàn)一個(gè)簡單的令牌桶限流器

    限流是在分布式系統(tǒng)中常用的一種策略,它可以有效地控制系統(tǒng)的訪問流量,保證系統(tǒng)的穩(wěn)定性和可靠性,在本文中,我將介紹如何使用Java自定義注解來實(shí)現(xiàn)一個(gè)簡單的令牌桶限流器,需要的朋友可以參考下
    2023-10-10
  • springboot整合mybatis分頁攔截器的問題小結(jié)

    springboot整合mybatis分頁攔截器的問題小結(jié)

    springboot整合mybatis分頁攔截器,分頁攔截實(shí)際上就是獲取sql后將sql拼接limit,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2021-07-07
  • SpringBoot應(yīng)用實(shí)現(xiàn)向釘釘發(fā)送帶圖片的消息的兩種方法總結(jié)

    SpringBoot應(yīng)用實(shí)現(xiàn)向釘釘發(fā)送帶圖片的消息的兩種方法總結(jié)

    在Spring Boot應(yīng)用中向釘釘發(fā)送帶圖片的消息,主要有兩種主流實(shí)現(xiàn)方式,一個(gè)是使用機(jī)器人Webhook,一個(gè)是通過釘釘開放平臺SDK,下面我們就來看看具體實(shí)現(xiàn)步驟吧
    2025-10-10
  • Java 如何遍歷JsonObject對象

    Java 如何遍歷JsonObject對象

    這篇文章主要介紹了Java 如何遍歷JsonObject對象?今天小編就為大家分享一篇Java遍歷JsonObject對象案例,希望對大家有所幫助吧
    2021-01-01
  • IDEA 單元測試覆蓋技巧分享

    IDEA 單元測試覆蓋技巧分享

    這篇文章主要介紹了IDEA 單元測試覆蓋技巧分享,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-01-01
  • java常用的定時(shí)任務(wù)框架及相關(guān)代碼應(yīng)用示例

    java常用的定時(shí)任務(wù)框架及相關(guān)代碼應(yīng)用示例

    在Java開發(fā)中,定時(shí)任務(wù)是一個(gè)常見的需求,比如定時(shí)備份數(shù)據(jù)、定時(shí)清理日志、定時(shí)發(fā)送郵件等,這篇文章主要介紹了java常用的定時(shí)任務(wù)框架及相關(guān)代碼應(yīng)用的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2025-11-11
  • 基于Java中對域和靜態(tài)方法的訪問不具有多態(tài)性(實(shí)例講解)

    基于Java中對域和靜態(tài)方法的訪問不具有多態(tài)性(實(shí)例講解)

    下面小編就為大家?guī)硪黄贘ava中對域和靜態(tài)方法的訪問不具有多態(tài)性(實(shí)例講解)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-10-10
  • 詳解Java中static關(guān)鍵字和內(nèi)部類的使用

    詳解Java中static關(guān)鍵字和內(nèi)部類的使用

    這篇文章主要為大家詳細(xì)介紹了Java中static關(guān)鍵字和內(nèi)部類的使用,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2022-08-08
  • Java中static與final關(guān)鍵字詳解(簡單易懂)

    Java中static與final關(guān)鍵字詳解(簡單易懂)

    在Java中static和final是兩個(gè)非常重要的關(guān)鍵字,它們各自具有獨(dú)特的作用,當(dāng)組合使用時(shí),還可以產(chǎn)生額外的效果,這篇文章主要介紹了Java中static與final關(guān)鍵字的相關(guān)資料,需要的朋友可以參考下
    2026-01-01

最新評論

双城市| 磐石市| 广德县| 英山县| 南京市| 齐河县| 池州市| 山西省| 莲花县| 安庆市| 石河子市| 桃江县| 泽州县| 新化县| 宜章县| 道孚县| 樟树市| 宜君县| 永康市| 通河县| 军事| 陆良县| 寻乌县| 江都市| 古蔺县| 弥勒县| 东源县| 若尔盖县| 泗水县| 岳普湖县| 龙岩市| 安康市| 和田县| 海伦市| 中江县| 石城县| 正阳县| 武功县| 仲巴县| 菏泽市| 古蔺县|