Storia della domanda:
Lo Stream API è stato introdotto in Java 8 per facilitare la programmazione funzionale e l'elaborazione parallela delle collezioni. Fornisce un modo conveniente per descrivere catene di operazioni sui dati tramite espressioni lambda.
Problema:
Senza lo Stream API, era necessario scrivere codice imperativo ingombrante per filtrare, ordinare e aggregare collezioni. Questo portava a potenziali errori, complessità di manutenzione e inefficienze nel tentativo di aggiungere parallelismo manualmente.
Soluzione:
Lo Stream API consente di costruire un pipeline di operazioni intermedie (intermediate) e terminali (terminal). I flussi sono pigri, lavorano con i dati in modo sequenziale o parallelo, e il codice diventa più compatto e espressivo.
Esempio di elaborazione di una collezione:
List<String> names = Arrays.asList("Anna", "Giovanni", "Pietro", "Eva"); names.stream() .filter(s -> s.length() > 3) .map(String::toUpperCase) .sorted() .forEach(System.out::println);
Caratteristiche chiave:
parallelStream()), ma è necessario tenere a mente la thread-safety delle collezioni e delle funzioniÈ possibile riutilizzare lo stesso Stream dopo la sua chiusura?
No, il tentativo di riutilizzare uno Stream chiuso solleva IllegalStateException. Il flusso è unico.
Influisce sulla collezione originale se viene modificata dopo la creazione dello Stream?
Sì, se la collezione viene modificata dopo la creazione dello Stream, ma prima dell'operazione terminale, possono verificarsi ConcurrentModificationException.
È possibile utilizzare variabili esterne modificabili all'interno delle operazioni Stream?
Non è consigliato, poiché in uno stream parallelo questo porta a errori imprevisti. È meglio evitare side-effect mutabili nel pipeline Stream.
.parallelStream() a collezioni non thread-safeUn programmatore chiama tramite Stream un certo metodo che modifica una lista esterna — ciò funziona durante l'esecuzione sequenziale, ma in parallelo porta a una struttura dati danneggiata.
Vantaggi:
Svantaggi:
L'intero pipeline è costruito in modo pulito: le operazioni non hanno side-effect, si utilizzano solo collezioni immutabili e il risultato finale è raccolto tramite collector.
Vantaggi:
Svantaggi: