我为自己编写了一个实用程序,将列表分解为给定大小的批次。我只是想知道是否已经有任何apache commons util用于此。

public static <T> List<List<T>> getBatches(List<T> collection,int batchSize){
    int i = 0;
    List<List<T>> batches = new ArrayList<List<T>>();
    while(i<collection.size()){
        int nextInc = Math.min(collection.size()-i,batchSize);
        List<T> batch = collection.subList(i,i+nextInc);
        batches.add(batch);
        i = i + nextInc;
    }

    return batches;
}

请让我知道是否有任何现有的公用事业已经相同。


当前回答

注意,List#subList()返回底层集合的视图,这在编辑较小的列表时可能会导致意想不到的结果——编辑将反映在原始集合中,或者可能抛出ConcurrentModificationException。

其他回答

这里有一个例子:

final AtomicInteger counter = new AtomicInteger();
final int partitionSize=3;
final List<Object> list=new ArrayList<>();
            list.add("A");
            list.add("B");
            list.add("C");
            list.add("D");
            list.add("E");
       
        
final Collection<List<Object>> subLists=list.stream().collect(Collectors.groupingBy
                (it->counter.getAndIncrement() / partitionSize))
                .values();
        System.out.println(subLists);

输入: [a, b, c, d, e]

输出: [a, b, c], [d, e]]

你可以在这里找到例子: https://e.printstacktrace.blog/divide-a-list-to-lists-of-n-size-in-Java-8/

我想到了这个:

private static <T> List<List<T>> partition(Collection<T> members, int maxSize)
{
    List<List<T>> res = new ArrayList<>();

    List<T> internal = new ArrayList<>();

    for (T member : members)
    {
        internal.add(member);

        if (internal.size() == maxSize)
        {
            res.add(internal);
            internal = new ArrayList<>();
        }
    }
    if (internal.isEmpty() == false)
    {
        res.add(internal);
    }
    return res;
}

检查Lists.partition(java.util。List, int) from谷歌Guava

返回列表的连续子列表,每个子列表的大小相同(最终列表可能更小)。例如,将包含[a, b, c, d, e]的列表划分为分区大小为3,将生成[[a, b, c], [d, e]]——一个包含三个和两个元素的两个内部列表的外部列表,所有元素都以原始顺序排列。

注意,List#subList()返回底层集合的视图,这在编辑较小的列表时可能会导致意想不到的结果——编辑将反映在原始集合中,或者可能抛出ConcurrentModificationException。

解决这个问题的另一个方法是:

public class CollectionUtils {

    /**
    * Splits the collection into lists with given batch size
    * @param collection to split in to batches
    * @param batchsize size of the batch
    * @param <T> it maintains the input type to output type
    * @return nested list
    */
    public static <T> List<List<T>> makeBatch(Collection<T> collection, int batchsize) {

        List<List<T>> totalArrayList = new ArrayList<>();
        List<T> tempItems = new ArrayList<>();

        Iterator<T> iterator = collection.iterator();

        for (int i = 0; i < collection.size(); i++) {
            tempItems.add(iterator.next());
            if ((i+1) % batchsize == 0) {
                totalArrayList.add(tempItems);
                tempItems = new ArrayList<>();
            }
        }

        if (tempItems.size() > 0) {
            totalArrayList.add(tempItems);
        }

        return totalArrayList;
    }

}