flatMap para colecciones anidadas
Aplane listas anidadas, cadenas de Optional y estructuras de líneas de archivos mediante flatMap.
flatMap para colecciones anidadas es una lección gratuita de Java Academy en CoddyKit. Esta es la lección 1 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Java Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Java Academy incluye 4 lecciones en total.
El problema de las colecciones anidadas
Cuando cada elemento de un flujo se transforma en otra colección, map produce un Stream<List<T>>. flatMap combina los flujos internos en un único Stream<T> plano.
List<List<Integer>> nested = List.of(List.of(1,2), List.of(3,4), List.of(5));
// With map:
Stream<List<Integer>> s = nested.stream().map(l -> l); // Stream<List<Integer>>
// With flatMap:
Stream<Integer> flat = nested.stream().flatMap(List::stream); // Stream<Integer>
flat.forEach(System.out::println); // 1 2 3 4 5flatMap frente a map
map(f) aplica f a cada elemento y envuelve el resultado. flatMap(f) aplica f, que devuelve un flujo, y después concatena todos esos flujos en uno solo.
// map: List<String> -> Stream<Stream<Character>>
Stream<Stream<Character>> nested = List.of("hi","bye").stream()
.map(s -> s.chars().mapToObj(c -> (char)c));
// flatMap: List<String> -> Stream<Character>
Stream<Character> flat = List.of("hi","bye").stream()
.flatMap(s -> s.chars().mapToObj(c -> (char)c));Aplanamiento de pedidos y artículos
Uso clásico: cada pedido tiene una lista de artículos. Obtenga un flujo plano con todos los artículos de todos los pedidos.
List<String> allItems = orders.stream()
.flatMap(order -> order.getItems().stream())
.collect(Collectors.toList());
System.out.println(allItems);flatMap con Optional
Utilice stream() en Optional (Java 9 o posterior) para convertirlo en un flujo de 0 o 1 elementos. Después, flatMap reduce un Stream<Optional<T>> a un Stream<T>.
List<Optional<String>> maybes = List.of(Optional.of("a"), Optional.empty(), Optional.of("c"));
List<String> values = maybes.stream()
.flatMap(Optional::stream) // Java 9+
.collect(Collectors.toList());
System.out.println(values); // [a, c]Lectura de todas las líneas de varios archivos
flatMap facilita la concatenación de todas las líneas de una lista de archivos en un único flujo, sin bucles anidados.
List<Path> files = List.of(Path.of("a.txt"), Path.of("b.txt"));
List<String> allLines = files.stream()
.flatMap(p -> {
try { return Files.lines(p); }
catch (IOException e) { return Stream.empty(); }
})
.collect(Collectors.toList());División de cadenas en palabras
Divida cada oración en palabras y aplane todas las palabras en un único flujo para contar su frecuencia.
List<String> sentences = List.of("hello world", "java streams rock");
Map<String, Long> freq = sentences.stream()
.flatMap(s -> Arrays.stream(s.split("\\s+")))
.collect(Collectors.groupingBy(w -> w, Collectors.counting()));
System.out.println(freq);flatMap con Map.entrySet
Aplane un mapa de categorías y listas de artículos en un flujo con todos los artículos.
Map<String, List<String>> catalog = Map.of(
"fruit", List.of("apple","banana"),
"veg", List.of("carrot","pea"));
List<String> all = catalog.values().stream()
.flatMap(List::stream)
.sorted()
.collect(Collectors.toList());
System.out.println(all); // [apple, banana, carrot, pea]Cómo evitar NullPointerException en flatMap
Si la función puede devolver null en lugar de un flujo, utilice una comprobación de nulidad o devuelva Stream.empty() para evitar NullPointerException.
departments.stream()
.flatMap(dept -> dept.getEmployees() == null
? Stream.empty()
: dept.getEmployees().stream())
.forEach(System.out::println);Conteo de palabras distintas con flatMap
Combine flatMap, distinct y count para procesar datos de forma concisa.
long distinctWords = sentences.stream()
.flatMap(s -> Arrays.stream(s.toLowerCase().split("[^a-z]+")))
.filter(w -> !w.isEmpty())
.distinct()
.count();
System.out.println("Distinct: " + distinctWords);flatMapToInt para flujos de tipos primitivos
Utilice flatMapToInt, flatMapToLong y flatMapToDouble para evitar el boxing al aplanar flujos de tipos primitivos.
int totalQuantity = orders.stream()
.flatMapToInt(order -> order.getItems().stream().mapToInt(Item::getQuantity))
.sum();
System.out.println("Total qty: " + totalQuantity);Nota sobre el rendimiento
Cada llamada a flatMap añade una capa de flujo. Para conjuntos de datos muy grandes con muchas colecciones internas pequeñas, considere utilizar enfoques iterativos o Spliterator para reducir la sobrecarga de crear objetos.
Comprobación rápida
Resumen
flatMap convierte cada elemento en un flujo y combina todos los flujos en uno solo. Utilícelo para aplanar colecciones anidadas, encadenar Optional, dividir cadenas y leer varios archivos. Utilice flatMapToInt para evitar el boxing.
Preguntas frecuentes
¿La lección «flatMap para colecciones anidadas» es gratis?
Sí — el texto completo de «flatMap para colecciones anidadas» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Java Academy, actualiza a CoddyKit PRO. El curso de Java Academy incluye 4 lecciones en total.
¿Qué aprenderé en «flatMap para colecciones anidadas»?
Aplane listas anidadas, cadenas de Optional y estructuras de líneas de archivos mediante flatMap. Practicas Java Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar Java Academy?
No se requiere experiencia previa. Java Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 1 de 4.
¿Cuánto tiempo toma la lección «flatMap para colecciones anidadas»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de Java Academy?
Sí. Cada lección de Java Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- flatMap para colecciones anidadas
- Streams paralelos: rendimiento y dificultades
- Spliterator: división para el paralelismo
- Streams infinitos con iterate y generate