2010-05-24 14 views

risposta

254

È possibile utilizzare subList(int fromIndex, int toIndex) per avere una vista di una porzione della lista originale.

Dal API:

restituisce una vista della porzione di questa lista tra specificata fromIndex, incluso e toIndex, esclusivo. (Se fromIndex e toIndex sono uguali, l'elenco restituito è vuoto.) L'elenco restituito è supportato da questo elenco, quindi le modifiche non strutturali nell'elenco restituito si riflettono in questo elenco e viceversa. L'elenco restituito supporta tutte le operazioni di elenco facoltativo supportate da questo elenco.

Esempio:

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

Se avete bisogno di queste liste tritate di essere non una vista, quindi è sufficiente creare un nuovo List dal subList. Ecco un esempio di mettere un paio di queste cose insieme:

// 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!) 
+10

+1 per una bella tritata (...) che fa uso di farmaci generici. –

+0

Elegante come soluzione superba –

+3

Credo che l'altra linea risponda usando librerie come Guava sono una scelta molto migliore. – johnnieb

3

Suppongo che il problema riscontrato sia la denominazione di 100 elenchi di array e il loro inserimento. È possibile creare una matrice di liste di array e popolare ciascuna di esse utilizzando un ciclo.

Il più semplice (leggi più stupida) modo per fare questo è come questo:

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

Una domanda simile è stato discusso qui, Java: split a List into two sub-Lists?

Principalmente è possibile utilizzare sottolista. Maggiori dettagli qui: subList

Restituisce una vista della parte di questo elenco tra fromIndex, inclusive e toIndex, esclusivo. (Se fromIndex e toIndex sono uguali, l'elenco restituito è vuoto.) L'elenco restituito è supportato da questo elenco, quindi le modifiche nell'elenco restituito si riflettono in questo elenco e viceversa. L'elenco restituito supporta tutte le operazioni sulle liste facoltative supportate da questa lista ...

150

È possibile aggiungere la libreria Guava al progetto e utilizzare il metodo Lists.partition, per esempio

+7

amo libs =), esattamente quello che stavo cercando – wutzebaer

+0

modifica l'elenco di sorgenti, mentre esegui il ciclo attraverso le sottoliste, otterrai un'eccezione concomitante, perché le statistiche del java doc: L'elenco esterno non è modificabile, ma riflette lo stato più recente del lista delle fonti. Le liste interne sono viste sublimate della lista originale. Questo è –

+0

questo è bellissimo! Grazie! – hariszhr

15

La risposta fornita da poligenelubrificanti suddivide un array in base alle dimensioni date. Stavo cercando un codice che suddividesse un array in un determinato numero di parti. Ecco la modifica che ho fatto al codice:

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

Spero che aiuti qualcuno.

+1

QUESTO è adorabile. Grazie mille! – Hellojeffy

+0

Perfetto !! Ho cercato questo da secoli – eouti

+0

Questo è fantastico! esattamente quello che sto cercando! – brazjul

1

È anche possibile utilizzare la libreria FunctionalJava - c'è il metodo partition per List. Questa libreria ha i propri tipi di raccolta, è possibile convertirli in raccolte java avanti e indietro.

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

Si divide la lista in 2 elenchi o 2 valori per lista. Ad esempio, se il tuo elenco iniziale fosse di 10 elementi, questo produrrebbe 2 elenchi di 5 o 5 elenchi di 2. – jDub9

+0

@ jDub9 funziona come richiesto nella domanda. Per 10 elementi restituisce 5 elenchi di 2. https://github.com/functionaljava/functionaljava/blob/6ac5f9547dbb1f0ca3777be6b366f256e9943194/core/src/main/java/fj/data/List.java#L886 –

41

Apache Commons Collections 4 ha un metodo dipartizione nella classe ListUtils. Ecco come funziona:

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

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

Funziona alla grande, meno codice per me mantenere, felice di usare i beni comuni. –

1

creare una nuova lista e aggiungere vista elenco secondario di elenco di origine utilizzando il metodo addAll per creare un nuovo elenco secondario
Lista newList = new ArrayList(); newList.addAll (sourceList.subList (startIndex, endIndex));

0

se non si vuole importare la libreria comuni apache provate questo semplice codice:

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

@Jaafar: Voglio lo stesso tipo ma dopo 20 elementi caricati, stampa di nuovo, ho bisogno di caricare i prossimi 20 elementi e così via.Quindi, per favore suggeriscimi per questo. – vasantha

+0

Ciao @vasantha scusa non ho visto la tua richiesta in anticipo, l'hai già fatto o no? –

4

Questo funziona per me

/** 
     * 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 
     */ 
     private <T> List<List<T>> getChunkList(List<T> largeList , int chunkSize) { 
      List<List<T>> chunkList = new ArrayList<>(); 
      for (int i = 0 ; i < largeList.size() ; i += chunkSize) { 
       chunkList.add(largeList.subList(i , i + chunkSize >= largeList.size() ? largeList.size() : i + chunkSize)); 
      } 
      return chunkList; 
     } 

Esempio:

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

È necessario conoscere la dimensione del blocco in base al quale yo stai dividendo la tua lista. Supponiamo che tu abbia un elenco di 108 entries e che tu abbia bisogno di una dimensione del blocco di 25. Così finirai con 5 lists:

  • 4 con 25 entries ciascuno;
  • 1 (il quinto) con 8 elements.

Codice:

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