[java] Java : 여러 작은 ArrayList에서 ArrayList를 어떻게 분할 할 수 있습니까?

같은 크기 (= 10)의 여러 ArrayList에서 ArrayList (size = 1000)를 어떻게 분할 할 수 있습니까?

ArrayList<Integer> results;



답변

subList(int fromIndex, int toIndex)원래 목록의 일부를 보는 데 사용할 수 있습니다 .

API에서 :

지정된 fromIndex, 포괄적 및 toIndex독점 사이에서이 목록 부분의 뷰를 리턴합니다 . ( fromIndextoIndex같으면 반환 된 목록이 비어 있습니다.) 반환 된 목록이이 목록을 기반으로하므로 반환 된 목록의 비 구조적 변경 사항이이 목록에 반영되며 그 반대도 마찬가지입니다. 리턴 된 목록은이 목록에서 지원하는 모든 선택적 목록 조작을 지원합니다.

예:

List<Integer> numbers = new ArrayList<Integer>(
    Arrays.asList(5,3,1,2,9,5,0,7)
);

List<Integer> head = numbers.subList(0, 4);
List<Integer> tail = numbers.subList(4, 8);
System.out.println(head); // prints "[5, 3, 1, 2]"
System.out.println(tail); // prints "[9, 5, 0, 7]"

Collections.sort(head);
System.out.println(numbers); // prints "[1, 2, 3, 5, 9, 5, 0, 7]"

tail.add(-1);
System.out.println(numbers); // prints "[1, 2, 3, 5, 9, 5, 0, 7, -1]"

잘린 목록이보기가 아닌 경우을 사용하여 새 목록을 만드 List십시오 subList. 다음은 이러한 것들 중 몇 가지를 결합한 예입니다.

// chops a list into non-view sublists of length L
static <T> List<List<T>> chopped(List<T> list, final int L) {
    List<List<T>> parts = new ArrayList<List<T>>();
    final int N = list.size();
    for (int i = 0; i < N; i += L) {
        parts.add(new ArrayList<T>(
            list.subList(i, Math.min(N, i + L)))
        );
    }
    return parts;
}


List<Integer> numbers = Collections.unmodifiableList(
    Arrays.asList(5,3,1,2,9,5,0,7)
);
List<List<Integer>> parts = chopped(numbers, 3);
System.out.println(parts); // prints "[[5, 3, 1], [2, 9, 5], [0, 7]]"
parts.get(0).add(-1);
System.out.println(parts); // prints "[[5, 3, 1, -1], [2, 9, 5], [0, 7]]"
System.out.println(numbers); // prints "[5, 3, 1, 2, 9, 5, 0, 7]" (unmodified!)


답변

Guava 라이브러리를 프로젝트에 추가하고 Lists.partition 메서드를 사용할 수 있습니다.

List<Integer> bigList = ...
List<List<Integer>> smallerLists = Lists.partition(bigList, 10);


답변

Apache Commons Collections 4 에는 클래스에 파티션 메소드가 ListUtils있습니다. 작동 방식은 다음과 같습니다.

import org.apache.commons.collections4.ListUtils;
...

int targetSize = 100;
List<Integer> largeList = ...
List<List<Integer>> output = ListUtils.partition(largeList, targetSize);


답변

polygenelubricants가 제공하는 답변은 주어진 크기를 기준으로 배열을 분할합니다. 배열을 주어진 수의 부분으로 나눌 코드를 찾고있었습니다. 코드를 수정 한 내용은 다음과 같습니다.

public static <T>List<List<T>> chopIntoParts( final List<T> ls, final int iParts )
{
    final List<List<T>> lsParts = new ArrayList<List<T>>();
    final int iChunkSize = ls.size() / iParts;
    int iLeftOver = ls.size() % iParts;
    int iTake = iChunkSize;

    for( int i = 0, iT = ls.size(); i < iT; i += iTake )
    {
        if( iLeftOver > 0 )
        {
            iLeftOver--;

            iTake = iChunkSize + 1;
        }
        else
        {
            iTake = iChunkSize;
        }

        lsParts.add( new ArrayList<T>( ls.subList( i, Math.min( iT, i + iTake ) ) ) );
    }

    return lsParts;
}

그것이 누군가를 돕기를 바랍니다.


답변

이것은 나를 위해 작동

/**
* Returns List of the List argument passed to this function with size = chunkSize
* 
* @param largeList input list to be portioned
* @param chunkSize maximum size of each partition
* @param <T> Generic type of the List
* @return A list of Lists which is portioned from the original list 
*/
public static  <T> List<List<T>> chunkList(List<T> list, int chunkSize) {
    if (chunkSize <= 0) {
        throw new IllegalArgumentException("Invalid chunk size: " + chunkSize);
    }
    List<List<T>> chunkList = new ArrayList<>(list.size() / chunkSize);
    for (int i = 0; i < list.size(); i += chunkSize) {
        chunkList.add(list.subList(i, i + chunkSize >= list.size() ? list.size()-1 : i + chunkSize));
    }
    return chunkList;
}

예 :

List<Integer> stringList = new ArrayList<>();
stringList.add(0);
stringList.add(1);
stringList.add(2);
stringList.add(3);
stringList.add(4);
stringList.add(5);
stringList.add(6);
stringList.add(7);
stringList.add(8);
stringList.add(9);

List<List<Integer>> chunkList = getChunkList1(stringList, 2);


답변

자바 8

크기 나 조건에 따라 목록을 분할 할 수 있습니다.

static Collection<List<Integer>> partitionIntegerListBasedOnSize(List<Integer> inputList, int size) {
        return inputList.stream()
                .collect(Collectors.groupingBy(s -> (s-1)/size))
                .values();
}
static <T> Collection<List<T>> partitionBasedOnSize(List<T> inputList, int size) {
        final AtomicInteger counter = new AtomicInteger(0);
        return inputList.stream()
                    .collect(Collectors.groupingBy(s -> counter.getAndIncrement()/size))
                    .values();
}
static <T> Collection<List<T>> partitionBasedOnCondition(List<T> inputList, Predicate<T> condition) {
        return inputList.stream().collect(Collectors.partitioningBy(s-> (condition.test(s)))).values();
}

그런 다음 다음과 같이 사용할 수 있습니다.

final List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
System.out.println(partitionIntegerListBasedOnSize(list, 4));  // [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10]]
System.out.println(partitionBasedOnSize(list, 4));  // [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10]]
System.out.println(partitionBasedOnSize(list, 3));  // [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]
System.out.println(partitionBasedOnCondition(list, i -> i<6));  // [[6, 7, 8, 9, 10], [1, 2, 3, 4, 5]]


답변

나는 당신이 겪고있는 문제가 100 ArrayLists의 이름을 지정하고 채우는 것이라고 생각합니다. ArrayList의 배열을 만들고 루프를 사용하여 각 배열을 채울 수 있습니다.

가장 간단한 (멍청한 읽기) 방법은 다음과 같습니다.

ArrayList results = new ArrayList(1000);
    // populate results here
    for (int i = 0; i < 1000; i++) {
        results.add(i);
    }
    ArrayList[] resultGroups = new ArrayList[100];
    // initialize all your small ArrayList groups
    for (int i = 0; i < 100; i++) {
            resultGroups[i] = new ArrayList();
    }
    // put your results into those arrays
    for (int i = 0; i < 1000; i++) {
       resultGroups[i/10].add(results.get(i));
    }