Java List 分批执行

最近在做一个批处理插入,需要对一个 List 中的数据通过批处理的方式插入到数据库当中去。但是目前发现List 数量过大导致单次拼接的SQL特别大,结果是拼接了SQL执行了大半天也没有执行完成。因此考虑到使用subList来给这个大 List 做个拆分,于是有了下面的代码。

public static void main(String[] args) {
    int limit = 10;
    for (int j = 0; j < 10000; j++) {
        // 测试生成随机的 List 的 size
        int size = new Random().nextInt(1000000000);
        int count = (int) Math.ceil(size / (double) limit);
        // 校验最后一批数据是否在 list 的序号区间中
        int i = count - 1;
        final int from = i * limit;
        final int to = Math.min(size, (i + 1) * limit);
        System.out.printf("current form : %d  , to %d . %n", from, to);
        // 校验是否能够符合逻辑
        Assert.assertTrue(from<to);
        System.out.printf("size : %d.%n", size);
    }
}

这里的代码主要是用来做测试使用的,技术难点在于如何设置分批,然后循环。

// 根据 List 的 size 和 每批的数量获取总共需要执行的批次
int count = (int) Math.ceil(size / (double) limit);

这里是通过’总数/每批的数量’来获取需要执行的批次,但如上面所示,当两个整数相除时,得到的是没有余数的上。这样会导致一个问题,也即我们计算得到的批次可能会比我们实际要执行的批次少一次。

如当我们共有 55 条数据,每批为 10 条时,我们如果直接用 ‘总数/每批的数量’,取得执行批次为5;当我们同样有50条数据,每批为10条时,同样取得批次为5,这样的话就会少执行一批数据。如下面代码所示:

public static void main(String[] args) {
    int limit = 10;
    int size = 55;
    int batch = size/limit;
    for(int i = 0;i < batch;i++){
    	// 这样编写代码会发现少执行一批数据,
    	//当为<=时则又会在数量为整除时多执行一批数据从而导致
    	// IndexOutBoundException
    	System.out.printf("from index %d to index %d%n",i*limit,(i+1)*limit);
	}
}

通过转换成浮点数计算的方式可以在由于余数的时候通过向上取整的方式多执行一批,然后通过下面代码来避免数组越界问题,即可完美解决分批问题。

final int to = Math.min(size, (i + 1) * limit);

完整的分批逻辑如下:

public static void main(String[] args) {
  int limit = 10;
  // 测试生成随机的 List 的 size
  int size = 55;
  int count = (int) Math.ceil(size / (double) limit);
  List<String> list = new ArrayList<>(size);
  for(int i = 0;i < count;i++){
     final int from = i * limit;
	 final int to = Math.min(size, (i + 1) * limit);
	 System.out.printf("current form : %d  , to %d . %n", from, to);
	 List<String> subList = list.subList(from,to);
	 // do your batch code
  }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值