Introduzione
Un Stream
in Java può essere visto come una sequenza di dati proveniente da una sorgente (ad esempio una collezione o array), su cui possiamo effettuare delle operazioni.
Tipi di Operazioni
Operazioni Intermedie vs Terminali
Le operazioni intermedie restituiscono un altro stream su cui continuare a lavorare.
- ad esempio:
map()
,filter()
,sorted()
Le operazioni terminali restituisco un tipo atteso e terminano lo stream impedendone il riutilizzo.
- ad esempio:
collet()
,sorted()
Operazione State-less vs State-full
Le operazioni state-less vengono elaborate in modo indipendente tra gli elementi, questo significa che possono essere parallelizzate.
- ad esempio:
filter()
Le operazioni state-full sono operazioni dove l’elaborazione di un elemento potrebbe dipendere da un altro elemento, e che quindi non possono essere parallelizzate.
- ad esempio:
sorted()
Lazy Behaviour
Le operazione intermedie non vengono eseguite immediatamente ma soltanto nel momento quando viene effettuata un operazione terminale.
Quest’approccio permette di ottimizzare il consumo di memoria e migliorare le prestazioni.
Tipi di Stream
Stream Sequenziali vs Paralleli
Un stream sequenziale ha un unico elemento corrente, elaborato in modo indipendente dagli altri.
Un stream parallelo è in grado di suddividere il suo lavoro in più parti, elaborando più elementi contemporaneamente.
Stream Primitivi
Gli stream normalmente possono lavorare solo su oggetti, per questo sono stati creati degli stream speciali soltanto per i primitivi, che non richiedono di passare attraverso le classi classi wrapper.
Ad esempio
IntStream
,DoubleStream
eLongStream
Come Creare uno stream
Per creare uno stream ci sono diversi modi:
Utilizzare Stream.of(elenco dati)
Stream.of(1,2,3,4)
Stream.of(new Persona("Mario"), new Persona "Giulia"))
Utilizzare il metodo stream()
o parallelStream()
delle collection:
List<Persona> persone = new ArrayList<>();
persone.stream();
persone.stream();
É possibile creare uno stream da un array utilizzare il metodo Array.stream(T[] array)
Integer[] numeri = {1, 2, 3, 4, 5};
Arrays.stream(numeri);
Uno stream di righe di testo da BufferedReader.lines()
, Files.lines(path)
e String.lines()
BufferedReader reader = new BufferedReader(new FileReader("file.txt"));
reader.lines() // lines è uno stream
Files.lines("file.txt") // lines è uno stream
String testo = "Linea 1\n Linea 2\n Linea 3";
testo.lines() // lines è uno stream
Stream Infiniti
È possibile creare degli stream infiniti attraverso il metodo iterate
che prende in input un valore iniziale e una funzione da allocare al valore iniziale per calcolare i successivi.
Stream<Integer> numeri = Stream.iterare(0, n -> n+10);
numeri.limit(5).forEach(System.out::println); // 0, 10, 20, 30, 40