捣鼓小玩意-分批处理工具类

分批处理工具类

博主自己的博客点击访问(内容大部分更新在自己的博客,有时间才会整理到CSDN)

  • 有时候会遇到一些大批量数据成千上万的列表,如果单独一个循环处理,可能会很慢,或者是遇到如需要根据id in ()去数据库查询,可能会遇到参数上限,此时就需要分割列表分批去查询,所以闲着没事的时候写了个工具类用于处理这类情况。
  • 这个工具类的使用需要对Function(四大函数式接口)以及Future类的了解。
package com.ruoyi.common.utils;import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.*;
import java.util.function.Function;/*** 批量处理工具类(需要写Function)** @author Zyyyyu* @date 2024 11-23 00:25:23*/
public class SplitBatchUtil {/*** Demo** @param args*/public static void main(String[] args) {List<String> list = new ArrayList<>();/** 初始化模拟数据 */for (int i = 0; i < 10000; i++) {list.add(i + ":" + "test");}/** 分批处理时需要执行的逻辑 */Function<List<String>, List<String>> function = ((l) -> {List<String> strings = new ArrayList<>();l.stream().forEach(item -> {String[] split = item.split(":");strings.add(split[0]);});System.out.println(strings);return strings;});/** 调用分批处理,第二个参数指的是每批多少条数据,第三个参数指的是是否开启多线程 */splitBatch(list, 10, true, function);}/*** @param list           需要处理的数据* @param batchSize      每批数据量* @param isBatchProcess 是否开启多线程处理* @param function       处理函数*/public static <T, R> void splitBatch(List<T> list, Integer batchSize, Boolean isBatchProcess, Function<List<T>, R> function) {/** 被分割的列表不能为空 */Objects.requireNonNull(list, "list cannot be null");if (list.isEmpty()) {return;}// 默认每批数据量final int DEFAULT_BATCH_SIZE = 50;// 批处理每批数据量if (null == batchSize || batchSize <= 0) {batchSize = DEFAULT_BATCH_SIZE;}// 待处理数据量int listSize = list.size();if (listSize <= batchSize) {// 直接处理function.apply(list);} else {// 计算需要的批数int batchNum = listSize / batchSize;if (listSize % batchSize != 0) {batchNum += 1;}// 判断是否开启Future多线程批处理if (!isBatchProcess) {for (int i = 0; i < batchNum; i++) {System.out.println("第" + (i + 1) + "批数据");int begin = i * batchSize;int end = Math.min((i + 1) * batchSize, listSize);List<T> subList = extractBatch(list, begin, end);// 执行处理函数function.apply(subList);}} else {/*** 创建固定大小的线程池* TODO 如果不需要开启多线程 可以将这个分支的逻辑进行删除*/ExecutorService executorService = Executors.newFixedThreadPool(5);/***  Future是通过多线程处理后将结果进行返回*  所以List<Future<T>> 的 T 是需要返回的数据类型*/List<Future<T>> futures = new ArrayList<>();for (int i = 0; i < batchNum; i++) {int begin = i * batchSize;int end = Math.min((i + 1) * batchSize, listSize);// 这里是提交任务Future<T> future = executorService.submit(new BatchProcessor(list, begin, end, i + 1, function));futures.add(future);}// 收集结果for (Future<T> future : futures) {try {T subList = future.get();} catch (InterruptedException | ExecutionException e) {e.printStackTrace();}}executorService.shutdown(); // 关闭线程池}}}/*** 提取指定范围的数据** @param list* @param start* @param end* @return*/private static <T> List<T> extractBatch(List<T> list, int start, int end) {List<T> batch = new ArrayList<>(end - start);for (int i = start; i < end; i++) {batch.add(list.get(i));}return batch;}/*** 批处理任务*/private static class BatchProcessor<T, R> implements Callable<List<T>> {private final List<T> list;private final int start;private final int end;private final int batchNumber;private final Function<List<T>, R> function;public BatchProcessor(List<T> list, int start, int end, int batchNumber, Function<List<T>, R> function) {this.list = list;this.start = start;this.end = end;this.batchNumber = batchNumber;this.function = function;}/*** 执行批处理任务* 在这里写要执行的业务逻辑** @return*/@Overridepublic List<T> call() {List<T> subList = extractBatch(list, start, end);System.out.println("线程:" + Thread.currentThread().getName() + " 第" + batchNumber + "批数据:");function.apply(subList);return subList;}}}

注意事项

Future一般用于先计算后才再处理结果,这里结果我直接忽略了,还没补充完整,所以有需要的可以自己补充

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/64462.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

提示词战术技巧-前导课

在人工智能的快速发展中,大模型(如OpenAI的GPT-4和GPT-4)为各行各业带来了革命性的变化。正确地选择适合的业务需求的大模型,并掌握提示词工程的编写与调优是成功实现AI应用的关键。本文旨在提供一个全面的教学指南,帮助学习者理解和掌握大模型的业务选型与提示词工程的技…

零配置打包工具 Parcel 的详细使用指南

前言 在前端开发中&#xff0c;选择一个高效且易用的打包工具至关重要。Parcel 作为一款零配置的 Web 应用打包工具&#xff0c;凭借其卓越的性能和简单的使用体验&#xff0c;赢得了众多开发者的青睐。它不仅能够自动处理依赖关系和代码打包&#xff0c;还支持热模块替换和多…

【AI知识】逻辑回归介绍+ 做二分类任务的实例(代码可视化)

1. 分类的基本概念 在机器学习的有监督学习中&#xff0c;分类一种常见任务&#xff0c;它的目标是将输入数据分类到预定的类别中。具体来说&#xff1a; 分类任务的常见应用&#xff1a; 垃圾邮件分类&#xff1a;判断一封电子邮件是否是垃圾邮件 。 医学诊断&#xff1a;…

删除 C 盘空文件夹--递归删除

# Language: Powershell # Style: TypeScript# 文件名: # "文件(夹)&#xff1a;删除空文件夹.ps1"function Remove-EmptyDirectories {param ([string]$Path)# 获取所有目录&#xff0c;把子目录排列在父目录前面。# 删除所有子文件(夹)后&#xff0c;可判断父目录为…

为SSH2协议服务器的用户设置密钥

目录 私钥的创建1. 在服务器上直接生成2. 如果需要配置免密登录3. 查看生成的密钥 导出私钥至SSH用户获取sudo权限 新的一台服务器类型是SSH2&#xff1a;这表示服务器支持SSH&#xff08;Secure Shell&#xff09;协议的第二个版本。SSH是一个网络协议&#xff0c;用于加密方式…

level2逐笔委托查询接口

沪深逐笔委托队列查询 前置步骤 分配数据库服务器 查询模板 以下是沪深委托队列查询的请求模板&#xff1a; http://<数据库服务器>/sql?modeorder_book&code<股票代码>&offset<offset>&token<token>查询参数说明 参数名类型说明mo…

微软开源GraphRAG的使用教程(最全,非常详细)

GraphRAG的介绍 目前微软已经开源了GraphRAG的完整项目代码。对于某一些LLM的下游任务则可以使用GraphRAG去增强自己业务的RAG的表现。项目给出了两种使用方式&#xff1a; 在打包好的项目状态下运行&#xff0c;可进行尝试使用。在源码基础上运行&#xff0c;适合为了下游任…

文献研读|基于像素语义层面图像重建的AI生成图像检测

前言&#xff1a;本篇文章主要对基于重建的AI生成图像检测的四篇相关工作进行介绍&#xff0c;分别为基于像素层面重建的检测方法 DIRE 和 Aeroblade&#xff0c;以及基于语义层面重建的检测方法 SimGIR 和 Zerofake&#xff1b;并对相应方法进行比较。 相关文章&#xff1a;论…

VScode MAC按任意键关闭终端 想要访问桌面文件

说明 最近配置MAC上CPP的运行环境&#xff0c;在安装必要的CPP插件后&#xff0c;配置launch和task等json文件后&#xff0c;点击运行三角形&#xff0c;每次都会跳出main想要访问桌面上的文件。并且输出也是在调试控制台&#xff0c;非常逆天。 尝试 尝试1:尽管我尝试将ta…

7.日常算法

1. NC140 排序 题目来源 要求使用堆进行排序 class Solution { public: void adjustDown(vector<int>& arr, int root, int n){int parent root;int chiled root * 2 1;while (chiled < n){if (chiled 1 < n && arr[chiled 1] > arr[chi…

Linux Shell 脚本编程基础知识篇

ℹ️大家好&#xff0c;我是练小杰&#xff0c;从本文是Linux shell脚本编程的基础知识内容&#xff0c;后续我会不断补充~~ 更多Linux 相关内容请点击&#x1f449;“Linux专栏”~ 假面驾驭&#xff0c;时王&#xff0c;假面骑士时王~~ 文章目录 什么是 Linux Shell主要功能…

QT绘制同心扇形

void ChartForm::paintEvent(QPaintEvent *) {QPainter painter(this);painter.setRenderHint(QPainter::Antialiasing);// 设置抗锯齿painter.save();// 设置无边框&#xff08;不需要设置QPen&#xff0c;因为默认是不绘制边框的&#xff09;QPen pen(Qt::NoPen);// QPen pen…

【0369】Postgres内核 checkpoint record 与 expectedTLEs 校验 ( 12 )

上一篇: 文章目录 1. checkpoint record 校验1.1 预期 timeline1.2 timeline 判断1.3 checkPoint ThisTimeLineID2. 最小 recovery point3. 初始化 LastRec1. checkpoint record 校验 如果 checkpoint record 的位置不在请求 timeline 历史中的预期 timeline 上,则无法继续…

TL3568/TL3562更改主机名,在Kernel用menuconfig失效

前言 最近在玩RK3562开发板&#xff0c;想改串口调试时看到的主机名&#xff0c;开发板的主机名默认是RK3562-Tronlong&#xff0c;如图&#xff1a; 按照之前玩T113开发版&#xff0c;在Kernel通过make menuconfig&#xff0c;可以改。但是在这个RK3562&#xff0c;改了后&…

【PLL】ISSCC 2024 Tutorial: Calibration Techniques in PLLs

1. 数字辅助模拟电路 为什么要辅助&#xff0c;或替换模拟电路&#xff1f; 利用CMOS管子尺寸缩小&#xff0c;降低功耗 和 减小面积校正模拟电路的 非线性行为 和 失配 数字辅助的好处&#xff1a; 简化模拟电路设计提高能源效率&#xff0c;提高准确度 2. 锁相环基础 2.1 概…

STM32-笔记5-按键点灯(中断方法)

1、复制03-流水灯项目&#xff0c;重命名06-按键点灯&#xff08;中断法&#xff09; 在\Drivers\BSP目录下创建一个文件夹exti&#xff0c;在该文件夹下&#xff0c;创建两个文件exti.c和exti.h文件&#xff0c;并且把这两个文件加载到项目中&#xff0c;打开项目工程文件 加载…

在M系列芯片的Mac上使用Uniapp开发的依赖安装指南

在M系列芯片的Mac上使用Uniapp开发的依赖安装指南 在基于M系列芯片&#xff08;例如M3、M4&#xff09;的Mac上进行Uniapp开发时&#xff0c;使用esbuild和rollup等依赖包时需要注意处理不同架构的支持。具体问题出现在darwin-arm64&#xff08;ARM架构&#xff09;和darwin-x…

Mvc、Springmvc框架

一.Mvc&#xff1a; 1.概念&#xff1a; MVC它是一种设计理念。把程序按照指定的结构来划分: Model模型 、View视图 、Controller控制层&#xff1b; 结构图&#xff1a; 二.Springmvc: 1.概念&#xff1a; springmvc框架它是spring框架的一个分支。它是按照mvc架构思想设计…

spring使用rabbitmq当rabbitmq集群节点挂掉 spring rabbitmq怎么保证高可用,rabbitmq网络怎么重新连接

##spring rabbitmq代码示例 Controller代码 import com.alibaba.fastjson.JSONObject; import com.newland.mi.config.RabbitDMMQConfig; import org.springframework.amqp.core.Message; import org.springframework.amqp.core.MessageProperties; import org.springframewo…

前端面试问题集合

0 HTML5相关 websocket WebSocket 使用ws或wss协议&#xff0c;Websocket是一个持久化的协议&#xff0c;相对于HTTP这种非持久的协议来说。WebSocket API最伟大之处在于服务器和客户端可以在给定的时间范围内的任意时刻&#xff0c;相互推送信息。WebSocket并不限于以Ajax(或X…