Diversi Modi per Creare uno Stream

Dopo aver diffusamente parlato degli Stream, introdotti in Java 8, negli articoli Collection e Stream in JavaParallel Stream in Java, vogliamo questa volta concentrarci sui diversi modi in cui uno Stream può essere creato/inizializzato.

Empty Stream

Il primo e più semplice modo per generare uno stream è attraverso il metodo empty() della classe  java.util.stream.Stream. Tale metodo è utile soprattutto quando su vuole evitare di restituire NULL nel caso di stream vuoti.

A Partire da Collezioni

La modalità sicuramente più comune per ottenere uno stream è partendo da un qualsiasi oggetto di tipo java.util.Collection (List, Queue, Set, etc.), attraverso il metodo stream() della classe Collection:

A Partire da Array

Altro modo tra i più comuni per ottenere uno stream è attraverso un oggetto di tipo java.util.Array o parte di esso, mediante il metodo statico stream() della classe Array, il quale ammette oltre, all’array sorgente, anche una coppia di indici di inizio e fine array.

La classe java.util.stream.Stream offre inoltre un metodo statico of() che consente di generare uno strema a partire da un array di oggetti (dello stesso tipo) forniti come input:

Stream Builder

Un utili metodo per la costruzione di uno stream è l’utilizzo del pattern Builder. A tale scopo la classe Stream fornisce metodo statico builder(), il cui uso richiede di esplicitarne il tipo nello statement.

Metodi generate() ed iterate()

Il metodo generate() della classe Stream utilizza un oggetto di tipo Supplier per generare uno stream. Supplier<T> è un’interfaccia funzionale introdotta in Java 8 nel package java.util.function. Il suo utilizzo è pensato principalmente per generare funzioni lambda senza input ma che ritornano un output di tipo specifico T->(). Nel nostro caso l’output fornito è utilizzato per generare lo stream:

Il metodo iterate() invece, utilizza un’altra interfaccia funzionale: UnaryOperator. Esso rappresenta un’operazione su un singolo operando che produce un risultato dello stesso tipo del l’operando. In altri termini rappresenta una specializzazione funzione lambda per il caso in cui l’operando e il risultato sono dello stesso tipo. Utilizzandola per generare uno stream come argomento di iterate() si può scrivere:

Java NIO

La generazione di stream è possibile anche da file per mezzo alla classe di utilità Files del package java.nio.file. In particolare il metodo lines() consente di generare uno stream da file di testo in cui ciascuna linea diviene un elemento dello stream:

Stream di Tipi Primitivi

Poiché Stream è un’interfaccia generica e non è possibile utilizzare tipi primitivi come parametro di tipo con tali interfacce, sono state create tre nuove interfacce specializzate: IntStream, LongStream, DoubleStream. L’utilizzo di tali interfacce mitica l’auto-boxing non necessario, consentendo una maggiore produttività. In particolare:

IntStream.range() Restituisce uno stream a partire da una coppia di indici ed incrementando di 1.
LongStream.rangeClosed() Restituisce uno stream a partire da una coppia di indici ed incrementando di 1.
Random.doubles()  Restituisce uno stream di numeri casuali.

Codice Sorgente

Il codice sorgente con tutti gli esempi mostrati è scaricabile qui stream-create.

© 2018 Java Boss - Theme by HappyThemes