2010-05-24 26 views

Respuesta

254

Puede utilizar subList(int fromIndex, int toIndex) para obtener una vista de una parte de la lista original.

De la API:

Devuelve una vista de la parte de esta lista se especifica entre el fromIndex, inclusive, y toIndex, exclusivo. (Si fromIndex y toIndex son iguales, la lista devuelta está vacía.) La lista devuelta está respaldada por esta lista, por lo que los cambios no estructurales en la lista devuelta se reflejan en esta lista, y viceversa. La lista devuelta admite todas las operaciones de lista opcionales admitidas por esta lista.

Ejemplo:

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

Si necesita estas listas para ser cortadas no es una vista, a continuación, simplemente crear una nueva List del subList. He aquí un ejemplo de poner algunas de estas cosas juntas:

// 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 para una hermosa picado (...) que hace uso de los genéricos. –

+0

Elegante como excelente solución –

+3

Creo que las respuestas de otra línea utilizando bibliotecas como Guava son una opción mucho mejor. – johnnieb

3

Supongo que el problema que está teniendo es nombrar 100 ArrayLists y poblarlos. Puede crear una matriz de ArrayLists y completar cada una de ellas utilizando un bucle.

El más simple (leer más estúpida) manera de hacer esto es así:

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 pregunta similar se discutió aquí, Java: split a List into two sub-Lists?

Principalmente se puede utilizar sublista. Más detalles aquí: subList

Devuelve una vista de la parte de esta lista entre fromIndex, inclusive, y toIndex, exclusivo. (Si fromIndex y toIndex son iguales, la lista devuelta está vacía.) La lista devuelta está respaldada por esta lista, por lo que los cambios en la lista devuelta se reflejan en esta lista, y viceversa. La lista devuelta soporta todas las operaciones de listas opcionales soportados por esta lista ...

150

Usted puede añadir la biblioteca Guava a su proyecto y utilizar el método Lists.partition, por ejemplo,

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

i love libs =), exactamente lo que estaba buscando – wutzebaer

+0

modificar la lista fuente, mientras recorre las sublistas, obtendrá una excepción concurrente, porque java doc stats: La lista externa no es modificable, pero refleja el estado más reciente de la lista de fuentes. Las listas internas son vistas de sublista de la lista original. Esto es –

+0

¡esto es hermoso! ¡Gracias! – hariszhr

15

La respuesta proporcionada por polygenelubricants divide una matriz según el tamaño. Estaba buscando un código que dividiera una matriz en una cantidad determinada de partes. Aquí es la modificación que hice para el código:

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

espero que ayude a alguien.

+1

ESTO es encantador. ¡Muchas gracias! – Hellojeffy

+0

¡Perfecto! He estado buscando esto desde los años – eouti

+0

¡Esto es genial! exactamente lo que estoy buscando! – brazjul

1

También puede usar la biblioteca FunctionalJava - existe el método partition para List. Esta lib tiene sus propios tipos de colección, puede convertirlos a colecciones java de ida y vuelta.

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

¿Está esto dividiendo su lista en 2 listas o 2 valores por lista? Por ejemplo, si su lista inicial era de 10 elementos, esto produciría 2 listas de 5 o 5 listas de 2. – jDub9

+0

@ jDub9, esto funciona como se requiere en la pregunta. Para 10 elementos, devuelve 5 listas de 2. https://github.com/functionaljava/functionaljava/blob/6ac5f9547dbb1f0ca3777be6b366f256e9943194/core/src/main/java/fj/data/List.java#L886 –

41

Apache Commons Collections 4 tiene una método partición en la clase ListUtils. Así es como funciona:

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

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

Funciona muy bien, con menos código para mí mantener, feliz de usar bienes comunes. –

1

crear una nueva lista y añadir mi lista secundaria de lista de fuentes utilizando el método addAll para crear una nueva lista secundaria
Lista newList = new ArrayList(); newList.addAll (sourceList.subList (startIndex, endIndex));

0

si no desea importar la biblioteca de apache commons prueba este código simple:

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: quiero lo mismo pero después de 20 elementos cargados, imprimo, entonces de nuevo, necesito cargar los siguientes 20 elementos, y así sucesivamente.Así que por favor sugiéreme para esto. – vasantha

+0

Hola @vasantha, lo siento, pero no he visto tu solicitud antes, ¿lo has hecho o no? –

4

Esto funciona para mí

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

Ej:

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

Necesita saber el tamaño del fragmento por el cual estás dividiendo tu lista. Supongamos que tiene una lista de 108 entries y necesita un tamaño de fragmento de 25. Por lo tanto, terminará con 5 lists:

  • teniendo 4 25 entries cada uno;
  • 1 (el quinto) que tiene 8 elements.

Código:

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