Java: làm thế nào tôi có thể chia một ArrayList trong nhiều ArrayLists nhỏ?


Câu trả lời:


325

Bạn có thể sử dụng subList(int fromIndex, int toIndex)để có được một phần của danh sách ban đầu.

Từ API:

Trả về một cái nhìn của một phần của danh sách này giữa chỉ định fromIndex, bao gồm và toIndexđộc quyền. (Nếu fromIndextoIndexbằng nhau, danh sách được trả về trống.) Danh sách được trả về được hỗ trợ bởi danh sách này, vì vậy những thay đổi phi cấu trúc trong danh sách được trả về được phản ánh trong danh sách này và ngược lại. Danh sách trả về hỗ trợ tất cả các hoạt động danh sách tùy chọn được hỗ trợ bởi danh sách này.

Thí dụ:

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]"

Nếu bạn cần các danh sách được cắt nhỏ này KHÔNG phải là một chế độ xem, thì chỉ cần tạo một danh sách mới Listtừ subList. Đây là một ví dụ về việc kết hợp một vài trong số những điều này lại với nhau:

// 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

Bạn có thể thêm thư viện Guava vào dự án của mình và sử dụng phương thức Lists.partition , vd

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

sửa đổi danh sách nguồn, trong khi lặp qua danh sách phụ, bạn sẽ nhận được một ngoại lệ đồng thời, bởi vì thống kê tài liệu java: Danh sách bên ngoài không thể thay đổi, nhưng phản ánh trạng thái mới nhất của danh sách nguồn. Các danh sách bên trong là khung nhìn danh sách con của danh sách ban đầu. Đây là
Junchen Liu

64

Bộ sưu tập Apache Commons 4 có một phương thức phân vùng trong ListUtilslớp. Đây là cách nó hoạt động:

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

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

26

Câu trả lời được cung cấp bởi polygenelubricants chia một mảng dựa trên kích thước đã cho. Tôi đang tìm kiếm mã sẽ chia một mảng thành một số phần nhất định. Đây là sửa đổi tôi đã làm với mã:

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

Hy vọng nó sẽ giúp được ai đó.


14

Điều này làm việc cho tôi

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

Ví dụ :

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
xin lưu ý rằng điều này có một lỗi mà nó bỏ qua tập dữ liệu cuối cùng. ex 201 được chia thành các khối 100 sẽ trả lại 100.100,0 thay vì 100.100,1
AAP

13

Java 8

Chúng tôi có thể phân chia một danh sách dựa trên một số kích thước hoặc dựa trên một điều kiện.

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

Sau đó, chúng ta có thể sử dụng chúng như:

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 Có thể áp dụng nhiều điều kiện (phương thức tĩnh thứ ba) để bạn có thể tạo nhiều danh sách ex [[1,2,3,4], [5,6,7,8,9], [10,11,12 , 13,14]] với các điều kiện: i <5, 5 <= i <10, i> = 10
gooornik07

2
@ gooornik07 một luồng chỉ có thể được sử dụng một lần.
akhil_mittal

3

Tôi đoán rằng vấn đề bạn gặp phải là khi đặt tên cho 100 ArrayLists và điền vào chúng. Bạn có thể tạo một mảng ArrayLists và điền vào từng mảng bằng cách sử dụng một vòng lặp.

Cách đơn giản nhất (đọc ngu ngốc nhất) để làm điều này là như thế này:

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

Một câu hỏi tương tự đã được thảo luận ở đây, Java: chia Danh sách thành hai Danh sách phụ?

Chủ yếu bạn có thể sử dụng danh sách phụ. Xem thêm chi tiết ở đây: sublist

Trả về chế độ xem phần của danh sách này giữa từ Index, bao gồm và to Index, độc quyền. (Nếu từ Index và to Index bằng nhau, danh sách được trả về trống.) Danh sách được trả về được hỗ trợ bởi danh sách này, vì vậy những thay đổi trong danh sách được trả lại được phản ánh trong danh sách này và ngược lại. Danh sách trả về hỗ trợ tất cả các hoạt động danh sách tùy chọn được hỗ trợ bởi danh sách này ...


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

Thí dụ

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

    chunkArrayList(test,10);

Đầu ra

CHUNKED :: [[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], .........

bạn sẽ thấy trong nhật ký của bạn


3

Bạn có thể sử dụng chunkphương thức từ Bộ sưu tập Eclipse :

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

Một vài ví dụ về chunkphương pháp cũng được bao gồm trong bài viết DZone này .

Lưu ý: Tôi là người đi làm cho Bộ sưu tập Eclipse.


2

Tạo một danh sách mới và thêm chế độ xem danh sách phụ của danh sách nguồn bằng phương thức addAll để tạo danh sách phụ mới
Danh sách newList = new ArrayList (); newList.add ALL (sourceList.subList (start Index, end Index));


1

Bạn cũng có thể sử dụng thư viện FunctionalJava - có partitionphương pháp cho List. Lib này có các loại bộ sưu tập riêng, bạn có thể chuyển đổi chúng thành các bộ sưu tập java qua lại.

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

Đây có phải là chia danh sách của bạn thành 2 Danh sách hoặc 2 giá trị cho mỗi Danh sách. Ví dụ: nếu danh sách ban đầu của bạn là 10 yếu tố thì điều này sẽ mang lại 2 danh sách gồm 5 hoặc 5 danh sách gồm 2
jDub9

@ jDub9 điều này hoạt động như nó được yêu cầu trong câu hỏi. Đối với 10 phần tử, nó trả về 5 danh sách gồm 2. github.com/feftaljava/feftaljava/blob/
mẹo

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

nếu bạn không muốn nhập thư viện apache commons, hãy thử mã đơn giản này:

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

@Jaafar: Tôi muốn giống như vậy nhưng sau 20 phần tử được tải in thì một lần nữa tôi cần tải 20 phần tử tiếp theo, v.v. Vì vậy, xin vui lòng đề nghị tôi cho điều này.
vasantha

Xin chào @vasantha xin lỗi tôi đã không thấy yêu cầu của bạn sớm, bạn đã thực hiện hay chưa?
B.JAAFAR

0

Để rõ ràng, Điều này vẫn phải được thử nghiệm thêm ...

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)

biết thêm chi tiết: https://e.printstacktrace.blog/divide-a-list-to-lists-of-n-size-in-Java-8/


-1

Bạn cần biết kích thước khối mà bạn đang chia danh sách của mình. Giả sử bạn có một danh sách 108 entriesvà bạn cần một kích thước lớn 25. Vì vậy, bạn sẽ kết thúc với 5 lists:

  • 4 có 25 entriesmỗi;
  • 1 (thứ năm) có 8 elements.

Mã số:

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());
        }
    }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.