HOWTO · Java

Dividir una lista en trozos en Java

Este tutorial demuestra cómo dividir una lista en varios fragmentos del mismo tamaño en Java.

En esta página

Para dividir una lista de Java en fragmentos de tamaño fijo sin añadir dependencias, recórrela avanzando de acuerdo con el tamaño de cada fragmento y obtén cada rango con List.subList(). Los collectors de Streams, Apache Commons Collections y Guava ofrecen alternativas si su forma de resultado o una dependencia que el proyecto ya utiliza se ajusta mejor a la tarea.

Usar List.subList() para dividir una lista en fragmentos en Java

List.subList(fromIndex, toIndex) devuelve una vista de un rango de la lista: el inicio se incluye y el final se excluye. Avanza el inicio según el tamaño del fragmento y limita el final a la longitud de la lista para que el último fragmento pueda ser más corto. Este ejemplo completo usa ocho valores y fragmentos de tres. Puedes seguir los rangos del bucle directamente a partir de los índices.

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class ChunkExample {
  public static void main(String[] args) {
    List<Integer> items = Arrays.asList(10, 20, 30, 40, 50, 60, 70, 80);
    int chunkSize = 3;
    List<List<Integer>> chunks = new ArrayList<>();

    for (int start = 0; start < items.size(); start += chunkSize) {
      int end = Math.min(start + chunkSize, items.size());
      chunks.add(items.subList(start, end));
    }

    System.out.println(chunks);
  }
}

Los inicios son 0, 3 y 6; el límite final se ajusta a la longitud de la lista. Así se conservan todos los valores, aunque el último rango sea más corto. Si no hay elementos de entrada, el bucle no añade ningún fragmento. El tamaño del fragmento debe ser positivo para que el bucle avance por la lista.

Cada resultado de subList() sigue respaldado por la lista original, en lugar de ser una copia independiente. Trata los fragmentos como vistas si necesitas que los cambios también se reflejen en la lista de origen. Los cambios estructurales en la lista de origen que se hagan fuera de la vista pueden volver poco fiable el uso posterior de una sublista. Para crear listas de fragmentos independientes, copia cada rango al añadirlo, por ejemplo, con new ArrayList<>(items.subList(start, end)).

Usar Java Streams para dividir una lista en fragmentos en Java

Un stream puede generar índices iniciales y asignar cada rango a una sublista. Una de las formas proporcionadas usa IntStream.iterate(0, i -> i < items.size(), i -> i + chunkSize) para generar los índices. Otra calcula la cantidad de rangos a partir de la longitud de la lista y del tamaño del fragmento, y después asigna cada índice i a un rango que comienza en i * chunkSize. Estas formas producen los mismos rangos que el bucle anterior; mantenlas en esta sección cuando elijas un enfoque basado en streams.

En ambas formas, la cantidad de rangos es cero si no hay elementos de entrada, y el tamaño del fragmento debe ser positivo antes de calcular el último índice. Aquí no se proporciona evidencia de ejecución en un entorno Java para estas formas con streams, por lo que el comportamiento de los índices se describe a partir de las API y la aritmética, no como un resultado probado. El bucle directo es más fácil de adaptar si quieres ver todos los límites en un mismo lugar.

Usar Collectors.groupingBy() para dividir una lista en fragmentos en Java

Collectors.groupingBy() agrupa los elementos de un stream según una clave de clasificación. Para formar fragmentos, clasifica cada elemento según su posición dividida por el tamaño del fragmento, no según su valor. Con posiciones basadas en cero, los índices desde 0 hasta chunkSize - 1 comparten una clave, y el rango siguiente comparte la clave siguiente.

Por ejemplo, genera un stream de los índices y agrúpalos con Collectors.groupingBy(i -> i / chunkSize); después, vuelve a asociar cada índice agrupado con items.get(i). El resultado es un mapa de números de fragmento a listas de valores. Si quien llama al método necesita una lista de listas, recopila los valores del mapa en una lista; no dependas del orden de iteración del mapa, a menos que el tipo de mapa elegido y su orden formen parte de la implementación. Como en los demás enfoques, usa un tamaño de fragmento positivo y contempla que la entrada no tenga elementos antes de calcular la cantidad de rangos.

Usar Apache Commons Collections para dividir una lista en fragmentos en Java

Si Apache Commons Collections ya es una dependencia del proyecto, su método ListUtils.partition() puede dividir una lista en fragmentos usando la lista y el tamaño del fragmento como argumentos: ListUtils.partition(items, chunkSize). Añade la biblioteca a la configuración de compilación antes de usar esta API; no forma parte del JDK. Consulta la versión que usa tu proyecto para conocer sus coordenadas de dependencia y los detalles de la API.

Aquí no se proporciona una versión de la biblioteca, una configuración de dependencias ni evidencia de ejecución. Por tanto, este artículo menciona el método, pero no garantiza si las particiones que devuelve son vistas o copias, si se pueden modificar ni cómo se comporta en otras situaciones específicas de una versión. Si esos detalles son importantes, consulta la documentación de la versión exacta de Commons Collections que usa tu compilación.

Usar Google Guava para dividir una lista en fragmentos en Java

Guava ofrece el método Lists.partition(), que se invoca con una lista y el tamaño del fragmento, como en Lists.partition(items, chunkSize). Es una opción basada en dependencias cuando la aplicación ya incluye Guava; de lo contrario, añade la biblioteca mediante el gestor de dependencias del proyecto antes de importar su API de colecciones.

Aquí no se proporciona una versión de Guava ni una configuración ejecutable de dependencias, así que el método no se presenta como un ejemplo probado. Confirma la API y cualquier comportamiento del que dependa tu aplicación con la versión de Guava elegida para el proyecto. El nombre del método por sí solo no garantiza que devuelva copias o vistas, que estas sean modificables ni el orden que tengan en una versión concreta.

Conclusión

Usa el bucle de índices con List.subList() cuando la tarea se ajuste a una solución que solo use el JDK y a la gestión explícita de los rangos. Elige una variante con streams si la asignación basada en índices encaja en el flujo de procesamiento, o usa Collectors.groupingBy() si te resulta útil un mapa cuyas claves sean los números de fragmento. Apache Commons Collections y Guava ofrecen alternativas concisas cuando el proyecto ya incluye esas dependencias. En todos los casos, elige un tamaño de fragmento positivo, contempla el último fragmento parcial y comprueba el comportamiento de las vistas o colecciones en la API y la versión de la dependencia que utilices.