जावा: मैं एक ArrayList को कई छोटे ArrayLists में कैसे विभाजित कर सकता हूं?


201

मैं एक ArrayList (आकार = 1000) को एक ही आकार के एकाधिक ArrayLists (= 10) में कैसे विभाजित कर सकता हूं?

ArrayList<Integer> results;

1
क्या आपको विचार या नए संग्रह की आवश्यकता है?
xuesheng

जवाबों:


325

आप subList(int fromIndex, int toIndex)मूल सूची के एक हिस्से को देखने के लिए उपयोग कर सकते हैं ।

एपीआई से:

निर्दिष्ट fromIndex, समावेशी और toIndex, अनन्य के बीच इस सूची के भाग का एक दृश्य देता है । (यदि fromIndexऔर toIndexबराबर हैं, लौटे सूची खाली है।) उपाध्यक्ष प्रतिकूल लौटे सूची इस सूची के द्वारा समर्थित है, इसलिए लौटे सूची में गैर-संरचनात्मक परिवर्तन इस सूची में परिलक्षित होते हैं, और। लौटी सूची इस सूची द्वारा समर्थित वैकल्पिक सूची संचालन के सभी का समर्थन करती है।

उदाहरण:

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

आप अपने प्रोजेक्ट में अमरुद की लाइब्रेरी को जोड़ सकते हैं और लिस्टपार्टिशन विधि का उपयोग कर सकते हैं , जैसे

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

स्रोत सूची को संशोधित करें, जबकि सब्लिस्ट्स के माध्यम से लूप, आपको एक समवर्ती अपवाद मिलेगा, क्योंकि जावा डॉक आँकड़े: बाहरी सूची अपरिवर्तनीय है, लेकिन स्रोत सूची की नवीनतम स्थिति को दर्शाती है। आंतरिक सूचियाँ मूल सूची के दृश्य हैं। यह है
जुन्चेन लियू

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

पॉलीजेनबेलिकेंट द्वारा प्रदान किया गया उत्तर दिए गए आकार के आधार पर एक सरणी को विभाजित करता है। मैं ऐसे कोड की तलाश में था जो किसी दिए गए भाग को एक सरणी में विभाजित कर दे। यहाँ मैंने कोड में संशोधन किया है:

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 ध्यान दें कि इसमें एक बग है जो डेटा के अंतिम सेट को अनदेखा करता है। 100 की चुन्नियों में टूटा हुआ पूर्व 201, 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 क्या कई शर्तें (तीसरी स्थैतिक विधि) लागू करना संभव है, इसलिए आप कई सूचियाँ बना सकते हैं [[१,२,३,४], [५,६,,8,,9, ९], [१०,११,१२१ , 13,14]] शर्तों पर: i <5, 5 <= i <10, i> 10 =
gooornik07

2
@ gooornik07 एक स्ट्रीम केवल एक बार उपयोग किया जा सकता है।
आखिल_मित्तल

3

मैं अनुमान लगा रहा हूं कि आपके पास जो समस्या है वह 100 ArrayLists के नामकरण और उन्हें आबाद करने के साथ है। आप ArrayLists की एक सरणी बना सकते हैं और एक लूप का उपयोग करने वालों में से प्रत्येक को आबाद कर सकते हैं।

ऐसा करने का सबसे सरल (मूर्खतापूर्ण) तरीका इस प्रकार है:

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

इसी तरह के सवाल पर यहां चर्चा की गई, जावा: एक सूची को दो उप-सूचियों में विभाजित करें?

मुख्य रूप से आप सबलिस्ट का उपयोग कर सकते हैं। यहाँ अधिक विवरण: subList

इस सूची के भाग के दृश्य को इंडेक्स, इनक्लूसिव, और इंडेक्स, एक्सक्लूसिव के बीच लौटाता है। (यदि इंडेक्स और इंडेक्स के बराबर हैं, तो लौटी हुई सूची खाली है।) लौटी हुई सूची इस सूची द्वारा समर्थित है, इसलिए लौटी सूची में परिवर्तन इस सूची में दिखाई देते हैं, और इसके विपरीत। लौटी सूची इस सूची द्वारा समर्थित सभी वैकल्पिक सूची संचालन का समर्थन करती है ...


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

उत्पादन

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

आप ग्रहण संग्रहchunk से विधि का उपयोग कर सकते हैं :

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

chunkइस DZone लेख में विधि के कुछ उदाहरणों को भी शामिल किया गया था ।

नोट: मैं ग्रहण संग्रहों के लिए एक कमिटेटर हूं।


2

एक नई सूची बनाएँ और एक नई सबलिस्ट बनाने के लिए स्रोत सूची का उपयोग करके सूची के सबलिस्ट देखें एक नया
सूची सूची बनाने के लिए newList = नया 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

@ jDub9 यह काम करता है क्योंकि यह प्रश्न में आवश्यक है। 10 तत्वों के लिए यह 2 की सूची देता है 2. github.com/functionaljava/functionaljava/blob/…
मिखाइल गोलूबट्सोव

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

@ जाफ़र: मैं वैसा ही चाहता हूं, लेकिन 20 एलिमेंट लोड होने के बाद फिर से मुझे अगले 20 एलिमेंट्स वगैरह लोड करने होंगे। तो कृपया इसके लिए मुझे सुझाव दें।
वसंता

हाय @ विश्वनाथ क्षमा करें, मैंने आपका अनुरोध जल्दी नहीं देखा, आपने ऐसा किया या नहीं?
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:

  • 4 25 entriesप्रत्येक;
  • 1 (पांचवां) होने 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());
        }
    }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.