如何在Java 8中创建ArrayList批处理?

4

我有一个包含1000个元素的对象ArrayList,我想将其分成大小为100的批次。

在Java 8中如何以优雅的方式实现?

我需要对以下实体进行迭代,其大小为1000:

List<CustomerAgreement> customerAgreement 

现在,我将在上述方法之后调用以下方法。
    customerAgreementDao.createAll(customerAgreement);
        customerAgreementDao.flush();

如何从上述实体创建批处理并在其中调用上述两种方法?

目前的标准做法有些类似于:

Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
for  ( int i=0; i<888888; i++ ) {
    TableA record = new TableA();
    record.setXXXX();
    session.save(record)
    if ( i % 50 == 0 ) { 
        session.flush();
        session.clear();
    }
}
tx.commit();
session.close();

@MaartenBodewes:好的,你的意思是我应该定义int batchForInsertsSize; initialValue = 0; int totalSize = customerAgreement.size(); 然后创建一个循环,使用totalsize/batchForInsertsSize,并在该循环中更改initialvalue和batchforinsertssize+initial value吗?这不是标准的做法吗? - fatherazrael
1
由于您正在执行终端操作并且没有返回任何内容,在这种情况下,您可以根据需要设计Consumer - bananas
1
我可以尝试制作一个。在此之前,请查看Stream#forEach(),它与您所寻找的类似。 - bananas
1
@fatherazrael 这确实是一种方法。毫无疑问,还有其他方法,甚至可能包括像emotionlessbananas将要向您展示的lambda函数。 - Maarten Bodewes
1
我同意@MaartenBodewes的观点。我所做的唯一事情就是为您的代码参考提供了一些花哨但有缺陷的实现,如下所示:public void consumerTest() { AtomicInteger ai = new AtomicInteger(0); IntStream.range(0, 100).boxed().map(Table::new) .forEach(r -> this.forEachConsumer(r, ai.addAndGet(1))); } public void forEachConsumer(Table table, Integer counter) { System.out.println(counter); if (counter % 30 == 0) { System.err.println(counter); } }不建议在生产环境中使用此代码 - bananas
显示剩余4条评论
2个回答

3

我自己会使用 List.subList,因为我不太喜欢使用 lambda 表达式;在我看来,它们通常会降低代码的可读性。

如果您不介意,可以尝试这个方法 - 我已经缩小了数组:

// create list as demo
var list = new ArrayList<String>();
for (int i = 0; i < 13; i++) {
    list.add(Integer.toString(i));
}

int batchSize = 3;

// the code
int offset = 0;
while (offset < list.size()) {
    // make sure the end offset doesn't go past the end
    int endOffset = Math.min(offset + batchSize, list.size());

    // call or add it to anything else, or even use streaming afterwards
    System.out.println(list.subList(offset, endOffset));
    offset = endOffset;
}

导致
[0, 1, 2]
[3, 4, 5]
[6, 7, 8]
[9, 10, 11]
[12]

注意,子列表不是副本,对列表中对象所做的任何更改都会反映在子列表中,而对原始列表的结构更改(如调整大小)可能会导致混乱。这也适用于另一种情况,尽管对subList进行结构更改是可能的。


对于任何不是不可变的对象,比如Java中的String,显然是无法进行更改的。没有黑魔法可以改变它们。 - Maarten Bodewes

2
    int itemsPerBatch = 100;
    int totalBatches = (customerAgreements.size()+itemsPerBatch-1)/itemsPerBatch;
    int offset = 0;
    for(int i=0; i<totalBatches; i++) {
        List<String> currentBatch = customerAgreements.subList(offset, Math.min(offset+itemsPerBatch, customerAgreements.size()));
        offset+=itemsPerBatch;
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接