工做中常常遇到分批处理的问题,好比将一个List列表中的数据分批次保存至数据库中。若是列表中数据条目很大,好比1000万条以上,mysql中 max_allowed_packet 所能容许的最大数据包量不支持如此大的数据量,这种状况下一次性保存处理就会出现保存失败。另外,过大的数据条目数量,在保存时也会致使性能降低。为此手动批量处置就成为了一种必须。这里给出分批处理的代码,方便之后直接使用。java
package com.lunyu.algorithm.service.base; import com.google.common.collect.Lists; import java.util.List; /** * @author lunyu * @since 2021/1/25 */ public class BaseService { /** * 每一个批次数据条目 */ private static final int BATCH_SIZE = 10; public static void main(String[] args){ List<Integer> list = Lists.newArrayList(); for (int i = 0; i < 23; i++){ list.add(i + 1); } // 获取执行的轮次 int round = (list.size() - 1) / BATCH_SIZE; for (int i = 0; i <= round; i++){ // 求每一个批次起始位置 int fromIndex = i * BATCH_SIZE; int toIndex = (i + 1) * BATCH_SIZE; // 若是是最后一个批次,则不能越界 if (i == round){ toIndex = list.size(); } List<Integer> subList = list.subList(fromIndex, toIndex); // TODO: 对subList执行进一步要作的操做 System.out.println("轮次:" + i); subList.forEach(e -> { System.out.print(e + ","); }); System.out.println(); } } }
这里有三个个注意的点,mysql
第一, 获取轮次使用 (list.size() - 1) / BATCH_SIZE ,这是为了方便将属于同一个批次的数据同属该批次。以代码为例,若是刚好有10个元素 1-10 (对应的坐标点 0-9 ),咱们要把它们放置在同一个批次下, BATCH_SIZE = 10; ,那么 list.size() - 1 = 9 ,刚好能够使最后一个元素和前面全部的元素都在一个批次下,这个批次等于 0。sql
第二,循环的轮次为 i <= round; ,这时为了保证全部的批次都能访问到。数据库
第三, if (i == round) ,要保证最后一个批次的数据,在获取时不能数组越界。数组