0Pricing
Java Academy · Lezione

flatMap per collezioni annidate

Appiattisca liste annidate, catene di Optional e strutture di righe di file usando flatMap.

flatMap per collezioni annidate è una lezione Java Academy gratuita su CoddyKit. Questa è la lezione 1 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Java Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Java Academy include 4 lezioni in totale.

Il problema delle collezioni annidate

Quando ogni elemento di uno stream viene trasformato in un'altra collezione, map restituisce un Stream<List<T>>. flatMap unisce gli stream interni in un unico Stream<T> piatto.

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 5

flatMap e map

map(f) applica f a ogni elemento e incapsula il risultato. flatMap(f) applica f, che restituisce uno stream, e concatena poi tutti questi stream in 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));

Appiattire ordini e articoli

Un caso d'uso classico: ogni ordine contiene un elenco di articoli. Si ottiene uno stream piatto con tutti gli articoli di tutti gli ordini.

List<String> allItems = orders.stream()
    .flatMap(order -> order.getItems().stream())
    .collect(Collectors.toList());
System.out.println(allItems);

flatMap con Optional

Utilizzi stream() su Optional (Java 9+) per convertirlo in uno stream con 0 o 1 elemento. Quindi flatMap riduce 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]

Leggere tutte le righe da più file

flatMap consente di concatenare facilmente in un unico stream tutte le righe di un elenco di file, senza cicli annidati.

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

Dividere le stringhe in parole

Divida ogni frase in parole e appiattisca tutte le parole in un unico stream per calcolare la frequenza delle parole.

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

Appiattisca una mappa di categorie associate a elenchi di articoli in uno stream contenente tutti gli articoli.

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]

Evitare NullPointerException in flatMap

Se la funzione può restituire null invece di uno stream, utilizzi un controllo per null oppure restituisca Stream.empty() per evitare NullPointerException.

departments.stream()
    .flatMap(dept -> dept.getEmployees() == null
        ? Stream.empty()
        : dept.getEmployees().stream())
    .forEach(System.out::println);

Contare le parole distinte con flatMap

Combini flatMap, distinct e count per un'elaborazione concisa dei dati.

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 per gli stream primitivi

Utilizzi flatMapToInt, flatMapToLong e flatMapToDouble per evitare il boxing quando appiattisce gli stream primitivi.

int totalQuantity = orders.stream()
    .flatMapToInt(order -> order.getItems().stream().mapToInt(Item::getQuantity))
    .sum();
System.out.println("Total qty: " + totalQuantity);

Nota sulle prestazioni

Ogni chiamata a flatMap aggiunge un livello di stream. Per dataset molto grandi con molte collezioni interne di piccole dimensioni, consideri approcci iterativi o Spliterator per ridurre l'overhead della creazione di oggetti.

Verifica rapida

In che modo flatMap differisce da map?

Riepilogo

flatMap converte ogni elemento in uno stream e unisce tutti gli stream in uno solo. Lo utilizzi per appiattire collezioni annidate, concatenare Optional, dividere stringhe e leggere più file. Utilizzi flatMapToInt per evitare il boxing.

Domande Frequenti

La lezione «flatMap per collezioni annidate» è gratuita?

Sì — il testo completo di «flatMap per collezioni annidate» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Java Academy, passa a CoddyKit PRO. Il corso Java Academy include 4 lezioni in totale.

Cosa imparerò in «flatMap per collezioni annidate»?

Appiattisca liste annidate, catene di Optional e strutture di righe di file usando flatMap. Eserciti Java Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Java Academy?

Non è richiesta alcuna esperienza precedente. Java Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 1 di 4.

Quanto tempo richiede la lezione «flatMap per collezioni annidate»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Java Academy?

Sì. Ogni lezione Java Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. flatMap per collezioni annidate
  2. Stream paralleli: prestazioni e insidie
  3. Spliterator: suddivisione per il parallelismo
  4. Stream infiniti con iterate e generate
← Torna a Java Academy