Java 使用ListUtils对List分页处理

背景分析

工作中,经常遇到需要用Java进行分页处理数据,例如把1000万条Excel数据写入MySQL数据库,如果把这1000w数据一股脑的丢给MySQL,保证把数据库玩完,故需要批量写入,如每批次写入500条。这时候就可以使用ListUtils.partition了。

maven坐标

commons-collections4和Guava两个jar包的坐标如下:

java 复制代码
<dependency>
	<groupId>org.apache.commons</groupId>
	<artifactId>commons-collections4</artifactId>
	<version>4.4</version>
</dependency>
<dependency>
	<groupId>com.google.guava</groupId>
	<artifactId>guava</artifactId>
	<version>31.0.1-jre</version>
</dependency>

批处理List

基于commons-collections4和Guava两个jar包,对java.util.List中海量数据进行分批处理的逻辑如下所示,请求参数都是传入List和每页处理的数据量:

java 复制代码
    public static void main(String[] args) {
        List<String> list =new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("d");
        list.add("Wiener");
        batchDealData(list, 3);
        batchDealByGuava(list, 3);
    }

    private static void batchDealData (List data, int batchNum) {

        // commons-collections4
        List<List<String>> partitions = ListUtils.partition(data, batchNum);
        partitions.stream().forEach(sublist -> {
            System.out.println(sublist);
        });
    }
    private static void batchDealByGuava (List data, int batchNum) {
        // guava
        List<List<String>> partitions = Lists.partition(data, batchNum);
        partitions.stream().forEach(sublist -> {
            System.out.println(sublist);
        });
    }

这种处理方法相对于手动分页,其优点显而易见,既可以降低代码复杂度,又可以提高开发效率。小编在《Java 使用线程池分批插入或者更新数据》中,介绍了一种通用分页方式,略显复杂,下面基于commons-collections4,优化其中的分页策略,代码如下:

java 复制代码
private void batchDeal(List<Object> data, int batchNum) throws InterruptedException {
        if (CollectionUtils.isEmpty(data)) {
            return;
        }
        // 使用 ListUtils.partition分页
        List<List<Object>> newList = ListUtils.partition(data, batchNum);
        // 计算总页数
        int pageNum = newList.size(); 
        ExecutorService executor = Executors.newFixedThreadPool(pageNum);
        try {
            CountDownLatch countDownLatch = new CountDownLatch(pageNum);
            for (int i = 0; i < pageNum; i++) {
                ImportTask task = new ImportTask(newList.get(i), countDownLatch);
                executor.execute(task);
            }
            countDownLatch.await();
            log.info("数据操作完成!可以在此开始其它业务");
        } finally {
            // 关闭线程池,释放资源
            executor.shutdown();
        }
    }
    // 无改动
    class ImportTask implements Runnable {
        private List list;
        private CountDownLatch countDownLatch;

        public ImportTask(List data, CountDownLatch countDownLatch) {
            this.list = data;
            this.countDownLatch = countDownLatch;
        }

        @Override
        public void run() {
            if (null != list) {
                // 业务逻辑,例如批量insert或者update
                log.info("现在操作的数据是{}", list);
            }
            // 发出线程任务完成的信号
            countDownLatch.countDown();
        }
    }

整理自:https://www.cnblogs.com/east7/p/15876727.html

相关推荐
毕设源码-朱学姐5 小时前
【开题答辩全过程】以 工厂能耗分析平台的设计与实现为例,包含答辩的问题和答案
java·vue.js
喵了meme5 小时前
C语言实战4
c语言·开发语言
码界奇点6 小时前
Python从0到100一站式学习路线图与实战指南
开发语言·python·学习·青少年编程·贴图
9ilk6 小时前
【C++】--- 特殊类设计
开发语言·c++·后端
sali-tec6 小时前
C# 基于halcon的视觉工作流-章68 深度学习-对象检测
开发语言·算法·计算机视觉·重构·c#
Spring AI学习7 小时前
Spring AI深度解析(9/50):可观测性与监控体系实战
java·人工智能·spring
java1234_小锋7 小时前
Spring IoC的实现机制是什么?
java·后端·spring
生骨大头菜8 小时前
使用python实现相似图片搜索功能,并接入springcloud
开发语言·python·spring cloud·微服务
绝不收费—免费看不了了联系我8 小时前
Fastapi的单进程响应问题 和 解决方法
开发语言·后端·python·fastapi
xqqxqxxq8 小时前
背单词软件技术笔记(V2.0扩展版)
java·笔记·python