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


답변:


325

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!)

213

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

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

java doc stats : 외부 목록은 수정할 수 없지만 소스 목록의 최신 상태를 반영하므로 소스 목록을 수정하는 동안 서브리스트를 반복하면서 동시에 예외가 발생합니다. 내부 목록은 원본 목록의 하위 목록보기입니다. 이것은
Junchen Liu

64

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);

26

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;
}

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


14

이것은 나를 위해 작동

/**
* 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);

3
pls는 이것이 마지막 데이터 세트를 무시한다는 버그가 있음을 주목하십시오. 예 201을 100 단위로 나누면 100,100,1 대신 100,100,0을 반환합니다.
AAP

13

자바 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]]

@i_am_zero 여러 조건을 적용 할 수 있습니까 (세번째 정적 방법). 예 [[1,2,3,4], [5,6,7,8,9], [10,11,12 , 13, 14] 조건 : 나 <5,5 <= I <10 난> = 10
gooornik07

2
@ gooornik07 스트림은 한 번만 사용할 수 있습니다.
akhil_mittal 10

3

나는 당신이 겪고있는 문제가 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));
    } 

3

비슷한 질문이 여기에서 논의되었습니다 .Java : List를 두 개의 하위 목록으로 나누시겠습니까?

주로 서브리스트를 사용할 수 있습니다. 자세한 내용은 여기 : subList

fromIndex (포함)와 toIndex (포함) 사이에서이 목록 부분의 뷰를 반환합니다. (fromIndex와 toIndex가 같으면 반환 된 목록이 비어 있습니다.) 반환 된 목록이이 목록을 기반으로하므로 반환 된 목록의 변경 내용이이 목록에 반영되며 그 반대도 마찬가지입니다. 리턴 된리스트는이리스트가 지원하는 모든 선택적리스트 조작을 지원합니다.


3
private ArrayList<List<String>> chunkArrayList(ArrayList<String> arrayToChunk, int chunkSize) {
    ArrayList<List<String>> chunkList = new ArrayList<>();
    int guide = arrayToChunk.size();
    int index = 0;
    int tale = chunkSize;
    while (tale < arrayToChunk.size()){
            chunkList.add(arrayToChunk.subList(index, tale));
            guide = guide - chunkSize;
            index = index + chunkSize;
            tale = tale + chunkSize;
    }
    if (guide >0) {
       chunkList.add(arrayToChunk.subList(index, index + guide));
    }
    Log.i("Chunked Array: " , chunkList.toString());
    return chunkList;
}

    ArrayList<String> test = new ArrayList<>();
    for (int i=1; i<=1000; i++){
        test.add(String.valueOf(i));
    }

    chunkArrayList(test,10);

산출

청크 :: [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [11, 12, 13, 14, 15, 16, 17, 18, 19, 20], [21 , 22, 23, 24, 25, 26, 27, 28, 29, 30], [31, 32, 33, 34, 35, 36, 37, 38, 39, 40], [41, 42, 43, 44 , 45, 46, 47, 48, 49, 50], [51, 52, 53, 54, 55, 56, 57, 58, 59, 60], [61, 62, 63, 64, 65, 66, 67 , 68, 69, 70], [71, 72, 73, 74, 75, 76, 77, 78, 79, 80], [81, 82, 83, 84, 85, 86, 87, 88, 89, 90 ], [91, 92, 93, 94, 95, 96, 97, 98, 99, 100], .........

당신은 당신의 로그에 표시됩니다


3

Eclipse Collections 에서 chunk메소드를 사용할 수 있습니다 .

ArrayList<Integer> list = new ArrayList<>(Interval.oneTo(1000));
RichIterable<RichIterable<Integer>> chunks = Iterate.chunk(list, 10);
Verify.assertSize(100, chunks);

chunk방법에 대한 몇 가지 예가이 DZone 기사 에도 포함되었습니다 .

참고 : 저는 Eclipse Collections의 커미터입니다.


2

addAll 메서드를 사용하여 새
목록 을 만들고 소스 목록의 하위 목록보기를 추가하여 새 하위 목록 을 만듭니다. List newList = new ArrayList (); newList.addAll (sourceList.subList (startIndex, endIndex));


1

FunctionalJava 라이브러리를 사용할 수도 있습니다 . partition방법이 List있습니다. 이 lib에는 자체 콜렉션 유형이 있으며이를 Java 콜렉션으로 변환 할 수 있습니다.

import fj.data.List;

java.util.List<String> javaList = Arrays.asList("a", "b", "c", "d" );

List<String> fList = Java.<String>Collection_List().f(javaList);

List<List<String> partitions = fList.partition(2);

이것은 목록을 2 개의 목록 또는 목록 당 2 개의 값으로 나누는 것입니다. 예를 들어, 초기 목록이 10 개 원소 인 경우 2 개 중 5 개 또는 5 개 중 2
개가 생성됩니다

@ jDub9 이것은 질문에 필요한대로 작동합니다. 10 개의 요소에
대해

1
import org.apache.commons.collections4.ListUtils;
ArrayList<Integer> mainList = .............;
List<List<Integer>> multipleLists = ListUtils.partition(mainList,100);
int i=1;
for (List<Integer> indexedList : multipleLists){
  System.out.println("Values in List "+i);
  for (Integer value : indexedList)
    System.out.println(value);
i++;
}

0

아파치 커먼즈 라이브러리를 가져 오지 않으려면 다음 간단한 코드를 사용해보십시오.

final static int MAX_ELEMENT = 20;

public static void main(final String[] args) {

    final List<String> list = new ArrayList<String>();

    for (int i = 1; i <= 161; i++) {
        list.add(String.valueOf(i));
        System.out.print("," + String.valueOf(i));
    }
    System.out.println("");
    System.out.println("### >>> ");
    final List<List<String>> result = splitList(list, MAX_ELEMENT);

    for (final List<String> entry : result) {
        System.out.println("------------------------");
        for (final String elm : entry) {
            System.out.println(elm);
        }
        System.out.println("------------------------");
    }

}

private static List<List<String>> splitList(final List<String> list, final int maxElement) {

    final List<List<String>> result = new ArrayList<List<String>>();

    final int div = list.size() / maxElement;

    System.out.println(div);

    for (int i = 0; i <= div; i++) {

        final int startIndex = i * maxElement;

        if (startIndex >= list.size()) {
            return result;
        }

        final int endIndex = (i + 1) * maxElement;

        if (endIndex < list.size()) {
            result.add(list.subList(startIndex, endIndex));
        } else {
            result.add(list.subList(startIndex, list.size()));
        }

    }

    return result;
}

@ Jafar : 같은 것을 원하지만 20 개의 요소가로드 된 후 다시 다음 20 개의 요소를로드해야합니다. 그래서 이것을 제안하십시오.
vasantha

안녕하세요 @vasantha 죄송합니다. 요청을 일찍 보지 못했습니다, 아직 보셨습니까?
B.JAAFAR

0

분명히하기 위해, 이것은 여전히 ​​더 많은 테스트가 필요합니다 ...

public class Splitter {

public static <T> List<List<T>> splitList(List<T> listTobeSplit, int size) {
    List<List<T>> sublists= new LinkedList<>();
    if(listTobeSplit.size()>size) {
    int counter=0;
    boolean lastListadded=false;

    List<T> subList=new LinkedList<>();

    for(T t: listTobeSplit) {           
         if (counter==0) {               
             subList =new LinkedList<>();
             subList.add(t);
             counter++;
             lastListadded=false;
         }
         else if(counter>0 && counter<size-1) {
             subList.add(t);
             counter++;
         }
         else {
             lastListadded=true;
             subList.add(t);
             sublists.add(subList);
             counter=0;
         }              
    }
    if(lastListadded==false)
        sublists.add(subList);      
    }
    else {
        sublists.add(listTobeSplit);
    }
    log.debug("sublists: "+sublists);
    return sublists;
 }
}

0
    **Divide a list to lists of n size**

    import java.util.AbstractList;
    import java.util.ArrayList;
    import java.util.List;

    public final class PartitionUtil<T> extends AbstractList<List<T>> {

        private final List<T> list;
        private final int chunkSize;

        private PartitionUtil(List<T> list, int chunkSize) {
            this.list = new ArrayList<>(list);
            this.chunkSize = chunkSize;
        }

        public static <T> PartitionUtil<T> ofSize(List<T> list, int chunkSize) {
            return new PartitionUtil<>(list, chunkSize);
        }

        @Override
        public List<T> get(int index) {
            int start = index * chunkSize;
            int end = Math.min(start + chunkSize, list.size());

            if (start > end) {
                throw new IndexOutOfBoundsException("Index " + index + " is out of the list range <0," + (size() - 1) + ">");
            }

            return new ArrayList<>(list.subList(start, end));
        }

        @Override
        public int size() {
            return (int) Math.ceil((double) list.size() / (double) chunkSize);
        }
    }





Function call : 
              List<List<String>> containerNumChunks = PartitionUtil.ofSize(list, 999)

자세한 내용 : https://e.printstacktrace.blog/divide-a-list-to-lists-of-n-size-in-Java-8/


-1

리스트를 나누는 청크 크기를 알아야합니다. 의 목록이 108 entries있고 청크 크기가 필요 하다고 가정하십시오 25. 따라서 다음과 5 lists같이 끝납니다 .

  • 25 entries각각 4 개 ;
  • 1 (5 번째) 8 elements.

암호:

public static void main(String[] args) {

        List<Integer> list = new ArrayList<Integer>();
        for (int i=0; i<108; i++){
            list.add(i);
        }
        int size= list.size();
        int j=0;
                List< List<Integer> > splittedList = new ArrayList<List<Integer>>()  ;
                List<Integer> tempList = new ArrayList<Integer>();
        for(j=0;j<size;j++){
            tempList.add(list.get(j));
        if((j+1)%25==0){
            // chunk of 25 created and clearing tempList
            splittedList.add(tempList);
            tempList = null;
            //intializing it again for new chunk 
            tempList = new ArrayList<Integer>();
        }
        }
        if(size%25!=0){
            //adding the remaining enteries 
            splittedList.add(tempList);
        }
        for (int k=0;k<splittedList.size(); k++){
            //(k+1) because we started from k=0
            System.out.println("Chunk number: "+(k+1)+" has elements = "+splittedList.get(k).size());
        }
    }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.