Java 中 List 分片的 5 种方法!

1ebdefba368db3c9bdef6202690a246b.png

作者 | 王磊

来源 | Java中文社群(ID:javacn666)

转载请联系授权(微信ID:GG_Stone)

前些天在实现 MyBatis 批量插入时遇到了一个问题,当批量插入的数据量比较大时,会导致程序执行报错,如下图所示:

d00d82a936910c3eb860cd6db5e308e5.png原因是 MySQL 只能执行一定长度的 SQL 语句,但当插入的数据量较多时,会生成一条很长的 SQL,这样程序在执行时就会报错。

要解决这个问题,有两种方法:第一,设置 MySQL 可以执行 SQL 的最大长度;第二,将一个大 List 分成 N 个小 List 进行。由于无法准确的界定程序中最大的 SQL 长度,所以最优的解决方案还是第二种,于是就有了今天的这篇文章。

简介

将一个 List 分成多个小 List 的过程,我们称之为分片,当然也可以叫做“List 分隔”,选一个你喜欢的、好理解的叫法就行。

在 Java 中,分片的常见实现方法有以下几种:

  1. 使用 Google 的 Guava 框架实现分片;

  2. 使用 Apache 的 commons 框架实现分片;

  3. 使用国产神级框架 Hutool 实现分片;

  4. 使用 JDK 8 中提供 Stream 实现分片;

  5. 自定义分片功能。

接下来我们分别来看。

1.Google Guava

先在项目的 pom.xml 中添加框架支持,增加以下配置:

<!-- google guava 工具类 -->
<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>31.0.1-jre</version>
</dependency>

有了 Guava 框架之后,只需要使用 Lists.partition 方法即可实现分片,如下代码所示:

import com.google.common.collect.Lists;import java.util.Arrays;
import java.util.List;/*** Guava 分片*/
public class PartitionByGuavaExample {// 原集合private static final List<String> OLD_LIST = Arrays.asList("唐僧,悟空,八戒,沙僧,曹操,刘备,孙权".split(","));public static void main(String[] args) {// 集合分片List<List<String>> newList = Lists.partition(OLD_LIST, 3);// 打印分片集合newList.forEach(i -> {System.out.println("集合长度:" + i.size());});}
}

以上代码的执行结果如下图所示:

94ebc605793fbbf2b59bcd5a968ac482.png

2.apache commons

先在项目的 pom.xml 中添加框架支持,增加以下配置:

<!-- apache 集合工具类 -->
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-collections4 -->
<dependency><groupId>org.apache.commons</groupId><artifactId>commons-collections4</artifactId><version>4.4</version>
</dependency>

有了  commons 框架之后,只需要使用 ListUtils.partition 方法即可实现分片,如下代码所示:

import org.apache.commons.collections4.ListUtils;import java.util.Arrays;
import java.util.List;/*** commons.collections4 集合分片*/
public class PartitionExample {// 原集合private static final List<String> OLD_LIST = Arrays.asList("唐僧,悟空,八戒,沙僧,曹操,刘备,孙权".split(","));public static void main(String[] args) {// 集合分片List<List<String>> newList = ListUtils.partition(OLD_LIST, 3);newList.forEach(i -> {System.out.println("集合长度:" + i.size());});}
}

以上代码的执行结果如下图所示:

b0c35608fdca26006ec9e9794d9b724f.png

3.Hutool

先在项目的 pom.xml 中添加框架支持,增加以下配置:

<!-- 工具类 hutool -->
<!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all -->
<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.7.14</version>
</dependency>

有了 Hutool 框架之后,只需要使用 ListUtil.partition 方法即可实现分片,如下代码所示:

import cn.hutool.core.collection.ListUtil;import java.util.Arrays;
import java.util.List;public class PartitionByHutoolExample {// 原集合private static final List<String> OLD_LIST = Arrays.asList("唐僧,悟空,八戒,沙僧,曹操,刘备,孙权".split(","));public static void main(String[] args) {// 分片处理List<List<String>> newList = ListUtil.partition(OLD_LIST, 3);newList.forEach(i -> {System.out.println("集合长度:" + i.size());});}
}

以上代码的执行结果如下图所示:

fa9e1e1f89d3c65cee3a98b74972641a.png

4.JDK

Stream 通过 JDK 8 中的  Stream 来实现分片就无需添加任何框架了,具体的实现代码如下:

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;/*** JDK Stream Partition*/
public class PartitionByStreamExample {// 原集合private static final List<Integer> OLD_LIST = Arrays.asList(1, 2, 3, 4, 5, 6);public static void main(String[] args) {// 集合分片:将大于 3 和小于等于 3 的数据分别分为两组Map<Boolean, List<Integer>> newMap = OLD_LIST.stream().collect(Collectors.partitioningBy(i -> i > 3));// 打印结果System.out.println(newMap);}
}

以上代码的执行结果如下图所示:

23f270c87a6dc9a1330258636519680a.png此方式的优点的无需添加任何框架,但缺点是只能实现简单的分片(将一个 List 分为两个),并且要有明确的分片条件。比如本篇案例中设置的分片条件就是数组是否大于 3,如果大于 3 就会被归为一组,否则就会被分到另一组。

5.自定义分片

如果你不想引入第三方框架,并且使用 Stream 也无法满足你的需求,你就可以考虑自己写代码来实现分片功能了。因为此方式不常用,所以咱们这里只给出关键方法。

自定义分片功能的关键实现方法是 JDK 自带的 subList 方法,如下图所示:

b8343480613d4c4a2f7f7aeafdf1a722.png使用示例如下:

import java.util.Arrays;
import java.util.List;public class App {private static final List<String> _OLD_LIST = Arrays.asList("唐僧,悟空,八戒,沙僧,曹操,刘备,孙权".split(","));public static void main(String[] args) {// 集合分隔List<String> list = _OLD_LIST.subList(0, 3);// 打印集合中的元素list.forEach(i -> {System.out.println(i);});}
}

以上代码的执行结果如下图所示:

2154f67c8dcc625760b263694ed3583a.png

总结

本文介绍了 5 种 List 分片的实现方法,其中最方便的实现方式是引入第三方框架,比如 Google 的 Guava、Apache 的 Commons 或者是国产开源的 Hutool 都可以,当然如果你的项目已经包含了以上任意一种,直接使用就行了。如果是简单的分片就可以考虑使用 JDK 的 Stream 或者是 List 内置的 subList 方法来实现分片功能了。

ac68611a24883bda8854f7918a29c9e4.gif

往期推荐

217ea051d6d9b340afaf7469937dc2f2.png

MyBatis原生批量插入的坑与解决方案!


2963019584410166c29b68864adcbd6c.png

4 种方法!检查字符串是否为合法的日期格式


3084c03986aff9b557d09138cea2fdb6.png

高并发下秒杀商品,必须知道的9个细节



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

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

相关文章

Matlab仿真炮弹飞行轨迹——探究射弹参数对飞行轨迹的影响

目录1.分析炮弹受力2.设定参数并仿真3.通过仿真寻找最佳射弹速度3.1.射弹角度的影响3.2.射弹速率的影响3.3.炮弹属性和空气的影响3.3.1.空气阻力系数的影响3.3.2.炮弹质量的影响1.分析炮弹受力 假设炮弹在飞行过程中可以看成质点&#xff0c;运动时仅考虑初始速度、重力加速度…

50行代码,搞定敏感数据读写!

每天早上七点三十&#xff0c;准时推送干货一、介绍在实际的软件系统开发过程中&#xff0c;由于业务的需求&#xff0c;在代码层面实现数据的脱敏还是远远不够的&#xff0c;往往还需要在数据库层面针对某些关键性的敏感信息&#xff0c;例如&#xff1a;身份证号、银行卡号、…

【Python】导入资源管理器的文件列表(计算文件和文件夹大小)

文章目录1.按照扩展名进行分类2.导出文件的大小3.计算文件夹大小4.分类到字典5.完整代码及效果1.按照扩展名进行分类 使用Python查询一个路径下的所有文件可以借助glob模块以及os模块。 在导入文件列表之前&#xff0c;我们需要指定我们的操作目录&#xff0c;操作目录一经指定…

HashMap 中的一个“坑”!

作者 | 王磊来源 | Java中文社群&#xff08;ID&#xff1a;javacn666&#xff09;转载请联系授权&#xff08;微信ID&#xff1a;GG_Stone&#xff09;最近公司新来了一个小伙伴&#xff0c;问了磊哥一个比较“奇怪”的问题&#xff0c;这个问题本身的难度并不大&#xff0c;但…

【Python】交互式界面创建函数

文章目录简介规则思路示例代码与运行效果简介 运行Python时&#xff0c;在程序运行过程中手动输入一个函数表达式&#xff0c;并将其作为一个函数进行后续的调用工作&#xff0c;类似于Matlab里面的匿名函数。这个功能使用传统语言会相当麻烦&#xff0c;当然&#xff0c;我也…

原生 js前端路由系统实现3之代码 构建工具 和 querystring功能

为什么80%的码农都做不了架构师&#xff1f;>>> 构建 目前前端构建工具流行的是 grunk.js 功能是大而全&#xff0c;但往往大而全的东西为了多样性 需要做额外的配置 我还是想要有一个专门为自己特性项目而生构建工具 我不想加载第三方的node模块&#xff0c;也不…

单例模式,真不简单

前言单例模式无论在我们面试&#xff0c;还是日常工作中&#xff0c;都会面对的问题。但很多单例模式的细节&#xff0c;值得我们深入探索一下。这篇文章透过单例模式&#xff0c;串联了多方面基础知识&#xff0c;非常值得一读。1 什么是单例模式&#xff1f;单例模式是一种非…

【python】最优化方法之一维搜索(黄金分割法+斐波那契法)

文章目录1.概念2.遍历搜索3.优化算法3.1.一维搜索原则3.2.黄金分割法Code Block3.3.斐波拉契法Code Block1.概念 \qquad一维搜索是最优化方法最简单的一种&#xff0c;即求一个在(a,b)内&#xff0c;连续下单峰函数f(x)f(x)f(x)的极小值。所谓下单峰函数就是只有一个极小值的函…

MySQL系列之E-1------MySQL主从复制原理

主从复制是异步复制,可以通过google的一个插件实现半同步E.1 主从复制原理1、建立主从复制的用户名和密码2、将master上主库需要进行复制的库“锁库”3、通过mysqldump备份master上主库&#xff0c;“解锁“&#xff0c;在slave端进行恢复4、更改配置文件5、在丛库上执行change…

工作中常用的 6 种设计模式!

前言 哈喽&#xff0c;大家好。平时我们写代码呢&#xff0c;多数情况都是流水线式写代码&#xff0c;基本就可以实现业务逻辑了。如何在写代码中找到乐趣呢&#xff0c;我觉得&#xff0c;最好的方式就是&#xff1a;使用设计模式优化自己的业务代码。今天跟大家聊聊日常工作中…

【Matlab/C/Python/VB/...】代码复制到word时如何变成彩色的

文章目录下载Notepad复制代码在Notepad粘贴在word中粘贴下载Notepad Notepad是一款免费的Windows软件&#xff0c;一般Windows10和Windows7系统都已经自带&#xff0c;也可以在应用商店直接搜索下载 「win10系统兼容的是7.8版本」 复制代码 在语言编辑乱码复制代码&#xff…

hadoop 2.5.0安装和配置

安装hadoop要先做以下准备&#xff1a; 1.jdk&#xff0c;安装教程在 http://www.cnblogs.com/stardjyeah/p/4640917.html 2.ssh无密码验证&#xff0c;配置教程在 http://www.cnblogs.com/stardjyeah/p/4641524.html 3.linux静态ip配置&#xff0c;教程在 http://www.cnblo…

基于双线性插值的图像旋转原理及MATLAB实现(非自带函数)

目录1.图像旋转的原理1.1.旋转矩阵1.2.双线性插值1.3.像素点匹配2.实现效果与说明1.图像旋转的原理 1.1.旋转矩阵 旋转一幅图像&#xff08;假设这幅图像大小是矩形的&#xff09;&#xff0c;当然应该从像素点&#xff08;pixels&#xff09;开始&#xff0c;在直角坐标系中…

漫画:给女朋友介绍什么是 “元宇宙” ?

什么是更高的自由度呢&#xff1f;或许有人觉得&#xff0c;我们在网络游戏当中&#xff0c;不是也很自由吗&#xff1f;想怎么玩就怎么玩。但是&#xff0c;无论一款网络游戏的元素有多么丰富&#xff0c;游戏当中的角色、任务、职业、道具、场景&#xff0c;都是游戏设计师预…

MyBatis 中为什么不建议使用 where 1=1?

作者 | 王磊来源 | Java中文社群&#xff08;ID&#xff1a;javacn666&#xff09;转载请联系授权&#xff08;微信ID&#xff1a;GG_Stone&#xff09;最近接手了一个老项目&#xff0c;“愉悦的心情”自然无以言表&#xff0c;做开发的朋友都懂&#xff0c;这里就不多说了&am…

【openMV与机器视觉】四旋翼飞行控制背景下的PID控制与摄像头算法简介

文章目录声明1.四旋翼飞行控制简介2.飞行控制算法2.1.接收机PWM生成2.2.PID算法位置PID速度PID3.摄像头算法3.1.图像处理3.2.霍夫曼变换3.3.巡线算法3.3.寻找目标点降落算法声明 \qquad本文的算法在openMV IDE例程的基础上进行原创&#xff0c;在比赛结束后予以发表&#xff1b…

聊聊sql优化的15个小技巧

前言sql优化是一个大家都比较关注的热门话题&#xff0c;无论你在面试&#xff0c;还是工作中&#xff0c;都很有可能会遇到。如果某天你负责的某个线上接口&#xff0c;出现了性能问题&#xff0c;需要做优化。那么你首先想到的很有可能是优化sql语句&#xff0c;因为它的改造…

【MATLAB】Parzen窗与K近邻算法原理与代码详解

文章目录1.非参数估计原理2.Parzen窗2.1.算法原理2.2.Matlab实现与参数探究3.K近邻3.1.算法原理3.2.Matlab实现与参数探究1.非参数估计原理 \qquad已知一个样本的概率分布时&#xff0c;我们只需要对概率分布中的参数进行估计即可得到该样本的概率密度函数。例如已知样本X服从正…

使用 Lambda 表达式实现超强的排序功能

我们在系统开发过程中&#xff0c;对数据排序是很常见的场景。一般来说&#xff0c;我们可以采用两种方式&#xff1a;借助存储系统&#xff08;SQL、NoSQL、NewSQL 都支持&#xff09;的排序功能&#xff0c;查询的结果即是排好序的结果查询结果为无序数据&#xff0c;在内存中…

【mongodb系统学习之四】查看mongodb进程

四、查看mongodb进程&#xff08;可以配合启动和关闭使用&#xff09;&#xff1a; 1&#xff09;、方法一&#xff1a;直接查看mongodb进程是否已经存在&#xff08;用上面的方式启动后&#xff0c;需要另开一个窗口操作&#xff09;&#xff1a;ps –ef|grep mongodb, 如图&a…