Java: bagaimana saya bisa membagi ArrayList dalam beberapa ArrayLists kecil?


Jawaban:


325

Kamu bisa memakai subList(int fromIndex, int toIndex) untuk mendapatkan sebagian dari daftar asli.

Dari API:

Mengembalikan tampilan porsi daftar ini antara yang ditentukan fromIndex, inklusif, dan toIndexeksklusif. (Jika fromIndexdan toIndexsama, daftar yang dikembalikan kosong.) Daftar yang dikembalikan didukung oleh daftar ini, sehingga perubahan non-struktural dalam daftar yang dikembalikan tercermin dalam daftar ini, dan sebaliknya. Daftar yang dikembalikan mendukung semua operasi daftar opsional yang didukung oleh daftar ini.

Contoh:

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

Jika Anda membutuhkan daftar cincang ini BUKAN tampilan, maka cukup buat yang baru Listdari subList. Berikut ini contoh menyatukan beberapa hal berikut:

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

Anda dapat menambahkan perpustakaan Guava ke proyek Anda dan menggunakan metode partisi Lists ., mis

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

memodifikasi daftar sumber, sementara perulangan melalui sublists, Anda akan mendapatkan pengecualian bersamaan, karena statistik java doc: Daftar luar tidak dapat dimodifikasi, tetapi mencerminkan keadaan terbaru dari daftar sumber. Daftar dalam adalah tampilan sublist dari daftar asli. Ini
Junchen Liu

64

Apache Commons Collections 4 memiliki metode partisi di ListUtilskelas. Begini cara kerjanya:

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

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

26

Jawaban yang diberikan oleh polygenelubricants membagi array berdasarkan ukuran yang diberikan. Saya sedang mencari kode yang akan membagi array menjadi sejumlah bagian. Ini modifikasi yang saya lakukan pada kode:

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

Semoga ini bisa membantu seseorang.


14

Ini bekerja untuk saya

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

Misalnya:

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
tolong perhatikan ini memiliki bug yang mengabaikan kumpulan data terakhir. ex 201 dipecah menjadi potongan 100-an akan mengembalikan 100.100,0 bukannya 100.100,1
AAP

13

Java 8

Kami dapat membagi daftar berdasarkan beberapa ukuran atau berdasarkan suatu kondisi.

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

Maka kita bisa menggunakannya sebagai:

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 Apakah mungkin menerapkan beberapa kondisi (metode statis ketiga) sehingga Anda dapat membuat beberapa daftar dari [[1,2,3,4], [5,6,7,8,9], [10,11,12 , 13,14]] dengan syarat: i <5, 5 <= i <10, i> = 10
gooornik07

2
@ gooornik07 stream hanya dapat digunakan sekali.
akhil_mittal

3

Saya menduga bahwa masalah yang Anda hadapi adalah dengan menyebutkan 100 ArrayLists dan mengisi mereka. Anda bisa membuat array ArrayLists dan mengisi masing-masing menggunakan loop.

Cara paling sederhana (baca paling bodoh) untuk melakukan ini adalah seperti ini:

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

Pertanyaan serupa didiskusikan di sini, Jawa: membagi Daftar menjadi dua sub-Daftar?

Terutama Anda dapat menggunakan sublist. Lebih detail di sini: subList

Mengembalikan tampilan porsi daftar ini antara fromIndex, inklusif, dan toIndex, eksklusif. (Jika dariIndex dan toIndex sama, daftar yang dikembalikan kosong.) Daftar yang dikembalikan didukung oleh daftar ini, sehingga perubahan dalam daftar yang dikembalikan tercermin dalam daftar ini, dan sebaliknya. Daftar yang dikembalikan mendukung semua operasi daftar opsional yang didukung oleh daftar ini ...


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

Contoh

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

    chunkArrayList(test,10);

Keluaran

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, 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, 89, 90 ], [91, 92, 93, 94, 95, 96, 97, 98, 99, 100], .........

Anda akan melihat di log Anda


3

Anda dapat menggunakan chunkmetode ini dari Eclipse Collections :

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

Beberapa contoh chunkmetode juga dimasukkan dalam artikel DZone ini .

Catatan: Saya pengendara untuk Eclipse Collections.


2

Buat daftar baru dan tambahkan tampilan sublist dari daftar sumber menggunakan metode addAll untuk membuat daftar sublist baru
newList = new ArrayList (); newList.addAll (sourceList.subList (startIndex, endIndex));


1

Anda juga dapat menggunakan perpustakaan FunctionalJava - ada partitionmetode untuk List. Lib ini memiliki jenis koleksi sendiri, Anda dapat mengonversinya ke koleksi java bolak-balik.

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

Apakah ini membagi daftar Anda menjadi 2 Daftar atau 2 nilai per Daftar. Misalnya, jika daftar awal Anda adalah 10 elemen, ini akan menghasilkan 2 daftar 5 atau 5 daftar 2.
jDub9

@ jDub9 ini berfungsi seperti yang diperlukan dalam pertanyaan. Untuk 10 elemen, ia mengembalikan 5 daftar 2. github.com/functionaljava/functionaljava/blob/…
Mikhail Golubtsov

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

jika Anda tidak ingin mengimpor pustaka apache commons coba kode sederhana ini:

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: Saya ingin yang sama seperti tetapi setelah 20 elemen dimuat cetak sekali lagi saya perlu memuat 20 elemen berikutnya dan seterusnya. Jadi tolong sarankan saya untuk ini.
vasantha

Hai @vasantha maaf saya tidak melihat permintaan Anda lebih awal, Anda sudah atau belum?
B.JAAFAR

0

Supaya jelas, Ini masih harus diuji lagi ...

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)

lebih detail: https://e.printstacktrace.blog/divide-a-list-to-lists-of-n-size-in-Java-8/


-1

Anda perlu mengetahui ukuran chunk yang digunakan untuk membagi daftar Anda. Katakanlah Anda memiliki daftar 108 entriesdan Anda memerlukan ukuran chunk 25. Dengan demikian Anda akan berakhir dengan 5 lists:

  • 4 25 entriesmasing - masing memiliki ;
  • 1 (yang kelima) memiliki 8 elements.

Kode:

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());
        }
    }
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.