当前位置: 首页 > 科技观察

CollectionList分片的五种实现

时间:2023-03-20 10:12:45 科技观察

前几天在实现MyBatis批量插入的时候遇到了一个问题。当批量插入的数据量比较大时,会报程序执行错误,如下图:原因是MySQL只能执行一定长度的SQL语句,但是当数据量很大时插入后,会生成很长的SQL,导致程序执行时报错。解决这个问题有两种方法:一是设置MySQL可以执行的SQL的最大长度;第二,将一个大的List分成N个小的List。由于在程序中无法准确定义最大SQL长度,最优解是第二种,所以才有了今天这篇文章。简介将一个List划分成多个小List的过程称为分片。当然,也可以称之为“列表分离”。只需选择一个您喜欢且易于理解的名称即可。在Java中,分片的常见实现方式有:使用Google的Guava框架实现分片;使用Apache的commons框架实现分片;使用国产神级框架Hutool实现分片;使用JDK8提供Stream实现Sharding;自定义分片功能。接下来我们分别来看一下。1、GoogleGuava首先在项目的pom.xml中添加框架支持,添加如下配置:com.google.guavaguava31.0.1-jre使用Guava框架,只需要使用Lists.partition方法实现分片,如下代码所示:importcom.google.common.collect.Lists;importjava.util.Arrays;importjava.util.List;publicclassPartitionByGuavaExample{privatestaticfinalListOLD_LIST=Arrays.asList("唐僧、悟空、八戒、沙僧、曹操、刘备、孙权"。分裂(”,”));publicstaticvoidmain(String[]args){List>newList=Lists.partition(OLD_LIST,3);newList.forEach(i->{System.out.println("集合长度:"+i.size());});}}上面代码的执行结果如下图所示:2.apachecommons首先在项目的pom.xml中添加framework支持,添加如下配置:org.apache.commonscommons-collections44.4</version>有了commons框架,只需要使用ListUtils.partition方法实现分片,如下代码:importorg.apache.commons.collections4.ListUtils;importjava.util.Arrays;importjava.util.List;publicclassPartitionExample{privatestaticfinalListOLD_LIST=Arrays.asList("唐僧、悟空、八戒、沙僧、曹操、刘备、孙权".split(","));publicstaticvoidmain(String[]args){List>newList=ListUtils.partition(OLD_LIST,3);newList.forEach(i->{System.out.println("集合长度:"+i.size());});}}上面代码的执行结果如下图所示:3.Hutool首先在项目的pom.xml中添加framework支持,添加如下配置:cn.hutoolhutool-all5.7.14使用Hutool框架,只需要使用ListUtil.partition方法实现分区,如下代码所示示例:importcn.hutool.core.collection.ListUtil;importjava.util.Arrays;importjava.util.List;publicclassPartitionByHutoolExample{privatestaticfinalListOLD_LIST=Arrays.asList("唐僧、悟空、八戒、沙僧、曹操、刘备、孙权".split(","));publicstaticvoidmain(String[]args){List>newList=ListUtil.partition(OLD_LIST,3);newList.forEach(i->{System.out.println("集合长度:"+i.size());});}}上面代码的执行结果如下图所示:4.JDKStream在JDK8中通过Stream实现分片,没有添加任何框架。具体实现代码如下:importjava.util.Arrays;导入java.util。列表;导入java.util.Map;导入java.util.stream.Collectors;公共类PartitionByStreamExample{privatestaticfinalListOLD_LIST=Arrays.asList(1,2,3,4,5,6);publicstaticvoidmain(String[]args){Map>newMap=OLD_LIST.stream().collect(Collectors.partitioningBy(i->i>3));System.out.println(newMap);}}上面代码的执行结果如下图所示:这种方法的优点不需要加任何框架,缺点是只能实现简单的分片(将一个List一分为二),必须要有明确的分片条件。比如本例中设置的分片条件是数组是否大于3,如果大于3则分到一组,否则分到另一组。5.自定义sharding如果不想引入第三方框架,使用Stream不能满足需求,可以考虑自己写代码实现sharding功能。因为这个方法不常用,所以这里只给出关键的方法。自定义分片功能的关键实现方法是JDK自带的subList方法,如下图:使用示例如下:importjava.util.Arrays;importjava.util.List;publicclassApp{privatestaticfinalList_OLD_LIST=Arrays.asList("唐僧、悟空、八戒、沙僧、曹操、刘备、孙权".split(","));publicstaticvoidmain(String[]args){Listlist=_OLD_LIST.subList(0,3);list.forEach(i->{System.out.println(i);});}}上面代码的执行结果如下图所示:总结本文介绍5种List分片最方便的实现方式是引入第三方框架,比如Google的Guava,Apache的Commons或者国内的open来源胡图。当然,如果你的项目已经包含了以上任何一个,直接使用即可。如果是简单的分片,可以考虑使用JDK的Stream或者List内置的subList方法来实现分片功能。