주어진 크기의 배치로 목록을 나누는 유틸리티를 스스로 작성했습니다. 나는 이미 아파치 커먼즈 유틸리티가 있는지 알고 싶었다.
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;
}동일한 기존 유틸리티가 있으면 알려주십시오.
답변
Google Guava 에서 확인하십시오 .  Lists.partition(java.util.List, int)
각각 크기가 동일한 목록의 연속 된 하위 목록을 반환합니다 (최종 목록은 더 작을 수 있음). 예를 들면, 포함 된리스트 분할
[a, b, c, d, e]3 개 수율의 파티션 크기[[a, b, c],[d, e]]원래 순서와 세 개의 요소들의 두 내측리스트 모두를 포함하는 목록을 외부 -.
답변
Java-8 배치 스트림을 생성하려는 경우 다음 코드를 시도 할 수 있습니다.
public static <T> Stream<List<T>> batches(List<T> source, int length) {
    if (length <= 0)
        throw new IllegalArgumentException("length = " + length);
    int size = source.size();
    if (size <= 0)
        return Stream.empty();
    int fullChunks = (size - 1) / length;
    return IntStream.range(0, fullChunks + 1).mapToObj(
        n -> source.subList(n * length, n == fullChunks ? size : (n + 1) * length));
}
public static void main(String[] args) {
    List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14);
    System.out.println("By 3:");
    batches(list, 3).forEach(System.out::println);
    System.out.println("By 4:");
    batches(list, 4).forEach(System.out::println);
}산출:
By 3:
[1, 2, 3]
[4, 5, 6]
[7, 8, 9]
[10, 11, 12]
[13, 14]
By 4:
[1, 2, 3, 4]
[5, 6, 7, 8]
[9, 10, 11, 12]
[13, 14]답변
또 다른 방법은 Collectors.groupingBy인덱스 를 사용한 다음 그룹화 된 인덱스를 실제 요소에 매핑하는 것입니다.
    final List<Integer> numbers = range(1, 12)
            .boxed()
            .collect(toList());
    System.out.println(numbers);
    final List<List<Integer>> groups = range(0, numbers.size())
            .boxed()
            .collect(groupingBy(index -> index / 4))
            .values()
            .stream()
            .map(indices -> indices
                    .stream()
                    .map(numbers::get)
                    .collect(toList()))
            .collect(toList());
    System.out.println(groups);산출:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11]]
답변
나는 이것을 생각해 냈습니다.
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;
}답변
Java 9 IntStream.iterate()에서는 hasNext조건 과 함께 사용할 수 있습니다 . 따라서 메소드 코드를 다음과 같이 단순화 할 수 있습니다.
public static <T> List<List<T>> getBatches(List<T> collection, int batchSize) {
    return IntStream.iterate(0, i -> i < collection.size(), i -> i + batchSize)
            .mapToObj(i -> collection.subList(i, Math.min(i + batchSize, collection.size())))
            .collect(Collectors.toList());
}사용 {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}의 결과가 getBatches(numbers, 4)될 것입니다 :
[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9]]답변
다음 예제는 목록 청크를 보여줍니다.
package de.thomasdarimont.labs;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class SplitIntoChunks {
    public static void main(String[] args) {
        List<Integer> ints = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
        List<List<Integer>> chunks = chunk(ints, 4);
        System.out.printf("Ints:   %s%n", ints);
        System.out.printf("Chunks: %s%n", chunks);
    }
    public static <T> List<List<T>> chunk(List<T> input, int chunkSize) {
        int inputSize = input.size();
        int chunkCount = (int) Math.ceil(inputSize / (double) chunkSize);
        Map<Integer, List<T>> map = new HashMap<>(chunkCount);
        List<List<T>> chunks = new ArrayList<>(chunkCount);
        for (int i = 0; i < inputSize; i++) {
            map.computeIfAbsent(i / chunkSize, (ignore) -> {
                List<T> chunk = new ArrayList<>();
                chunks.add(chunk);
                return chunk;
            }).add(input.get(i));
        }
        return chunks;
    }
}산출:
Ints:   [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
Chunks: [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11]]답변
이 질문 의 복제본으로 닫히는 또 다른 질문 이 있었지만 자세히 읽으면 미묘하게 다릅니다. 따라서 누군가 (나 같은 사람)가 실제로 목록을 주어진 수의 거의 동일한 크기의 하위 목록으로 나누기를 원할 경우 다음 계속 읽으십시오.
여기 에 설명 된 알고리즘 을 Java로 간단히 포팅했습니다 .
@Test
public void shouldPartitionListIntoAlmostEquallySizedSublists() {
    List<String> list = Arrays.asList("a", "b", "c", "d", "e", "f", "g");
    int numberOfPartitions = 3;
    List<List<String>> split = IntStream.range(0, numberOfPartitions).boxed()
            .map(i -> list.subList(
                    partitionOffset(list.size(), numberOfPartitions, i),
                    partitionOffset(list.size(), numberOfPartitions, i + 1)))
            .collect(toList());
    assertThat(split, hasSize(numberOfPartitions));
    assertEquals(list.size(), split.stream().flatMap(Collection::stream).count());
    assertThat(split, hasItems(Arrays.asList("a", "b", "c"), Arrays.asList("d", "e"), Arrays.asList("f", "g")));
}
private static int partitionOffset(int length, int numberOfPartitions, int partitionIndex) {
    return partitionIndex * (length / numberOfPartitions) + Math.min(partitionIndex, length % numberOfPartitions);
}