Java: Bir ArrayList'i birden çok küçük ArrayLists'e nasıl bölebilirim?


Yanıtlar:


325

subList(int fromIndex, int toIndex)Orijinal listenin bir bölümünün görünümünü görmek için kullanabilirsiniz .

API'dan:

Bu listenin belirtilen fromIndex, kapsayıcı ve toIndexözel arasındaki bölümünün bir görünümünü döndürür . ( fromIndexVe toIndexeşitse, döndürülen liste boştur.) Döndürülen liste bu listeyle desteklenir, bu nedenle döndürülen listedeki yapısal olmayan değişiklikler bu listeye yansıtılır veya tersi de geçerlidir. Döndürülen liste, bu liste tarafından desteklenen tüm isteğe bağlı liste işlemlerini destekler.

Misal:

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

Bu kıyılmış listeleri gerekirse sonra sadece yeni oluşturmak DEĞİL bir görünüm olması Listden subList. İşte bunlardan birkaçını bir araya getirme örneği:

// 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 kütüphanesini projenize ekleyebilir ve Lists.partition yöntemini kullanabilirsiniz;

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

alt listeler arasında döngü yaparken, eşzamanlı bir istisna alırsınız, çünkü java doc istatistikleri: Dış liste değiştirilemez, ancak kaynak listesinin en son durumunu yansıtır. İç listeler orijinal listenin alt liste görünümleridir. Bu
Junchen Liu

64

Apache Commons Collections 4 sınıfta bir bölümleme yöntemine sahiptir ListUtils. Şöyle çalışır:

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

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

28

Poligeno-yağlayıcılar tarafından verilen cevap verilen boyuta göre bir dizi ayırır. Belirli bir sayıda parçaya bir dizi bölecek kod arıyordu. İşte kodda yaptığım değişiklik:

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

Umarım birine yardımcı olur.


14

Bu benim için çalışıyor

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

Örneğin :

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 bunun son veri kümesini yok sayar bir hata olduğunu unutmayın. 100'lük parçalara bölünen eski 201, 100.100,1 yerine 100.100,0 döndürecek
AAP

13

Java 8

Bir listeyi belirli bir boyuta veya bir koşula bağlı olarak bölebiliriz.

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

Sonra bunları şu şekilde kullanabiliriz:

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 Birden fazla koşul (üçüncü statik yöntem) uygulamak mümkün mü, böylece [[1,2,3,4], [5,6,7,8,9], [10,11,12 gibi birden çok liste oluşturabilirsiniz , 13,14]] şartlarda: i <5, 5 <= i <10, i> = 10
gooornik07

2
@ gooornik07 bir akış yalnızca bir kez kullanılabilir.
akhil_mittal

3

Sanırım yaşadığınız sorun 100 ArrayLists isimlendirmek ve onları doldurmak. Bir dizi ArrayLists oluşturabilir ve bunların her birini bir döngü kullanarak doldurabilirsiniz.

Bunu yapmanın en basit (en aptalca) yolu şöyledir:

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

Benzer bir soru burada tartışıldı, Java: Bir Listeyi iki alt Listeye bölmek mi?

Temelde alt listeyi kullanabilirsiniz. Daha fazla ayrıntı burada: subList

Bu listenin fromIndex, inclusive ve toIndex, exclusive arasındaki bölümünün bir görünümünü döndürür. (FromIndex ve toIndex eşitse, döndürülen liste boştur.) Döndürülen liste bu listeyle desteklenir, bu nedenle döndürülen listedeki değişiklikler bu listeye yansıtılır veya tersi de geçerlidir. Döndürülen liste, bu liste tarafından desteklenen tüm isteğe bağlı liste işlemlerini destekler ...


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

Misal

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

    chunkArrayList(test,10);

Çıktı

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], .........

kütüğünde göreceksin


3

Eclipse Collections'takichunk yöntemi kullanabilirsiniz :

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

chunkYöntemin birkaç örneği de bu DZone makalesine dahil edildi .

Not: Eclipse Collections için bir komisyoncuyum.


2

Yeni bir alt liste oluşturmak ve yeni bir alt liste oluşturmak için addAll yöntemini kullanarak kaynak listesinin alt liste görünümünü ekleyin
List newList = new ArrayList (); newList.addAll (sourceList.subList (startIndex, endIndex));


1

FunctionalJava kütüphanesini de kullanabilirsiniz - bunun için bir partitionyöntem var List. Bu lib'in kendi koleksiyon türleri vardır, bunları java koleksiyonlarına ileri geri dönüştürebilirsiniz.

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

Bu, listenizi Liste veya Liste başına 2 değere böler mi? Örneğin, ilk listeniz 10 öğe olsaydı, bu 2 veya 5 listeden oluşan 2 liste olurdu.
jDub9

@ jDub9 bu soruda gerektiği gibi çalışır. 10 element için 5 listeyi 2 döndürür. 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

apache commons kütüphanesini içe aktarmak istemiyorsanız bu basit kodu deneyin:

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: Ben de aynı istiyorum ama 20 eleman baskı yüklendikten sonra tekrar sonraki 20 eleman yüklemek gerekir ve böylece. Lütfen bunun için bana öner.
vasantha

Merhaba @vasantha üzgünüm isteğinizi erken görmedim, henüz ya da değil mi?
B.JAAFAR

0

Sadece açık olmak gerekirse, bu hala daha fazla test edilmelidir ...

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)

daha fazla detay: https://e.printstacktrace.blog/divide-a-list-to-lists-of-n-size-in-Java-8/


-1

Listenizi böldüğünüz yığın boyutunu bilmeniz gerekir. Diyelim ki bir listeniz var 108 entriesve yığın boyutuna ihtiyacınız var 25. Böylece aşağıdakilerle sonuçlanacaksınız 5 lists:

  • 25 entriesHer birine sahip 4 ;
  • 1 (beşinci) sahip 8 elements.

Kod:

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());
        }
    }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.