Streams y pipelines
Los objetos de las clases que implementan la interfaz Stream son sucesiones de objetos sobre los que se pueden realizar una serie de operaciones que pueden ir encadenadas hasta dar un resultado final.
Dichas operaciones pueden ser de dos tipos:
- Intermedias: dan como resultado un nuevo
Streamal que se le pueden seguir aplicando nuevas operaciones. - Terminales: dan un resultado final, numérico o de otro tipo, pero no
Stream.
La idea es crear, a partir de una colección o array, un Stream al que se le apliquen operaciones intermedias, obteniendo un resultado final por medio de una operación terminal.
Los objetos Stream no se pueden crear con un constructor porque es una interfaz.
Obtener streams
Hay varias formas de obtener un Stream inicial, es decir, que no proceda de otro Stream.
A partir de una colección, llamando al método stream():
Stream<T> nombreStream = nombreColeccion.stream();
Además, se puede obtener de una serie de objetos o de un array, utilizando el método estático de Stream of():
Stream<T> nombreStream = Stream.of(T[] array);
Stream<T> nombreStream = Stream.of(T obj1, T obj2, ...);
Vamos a crear un Stream a partir de una lista:
List<String> lista = new ArrayList<>();
lista.add("dado");
lista.add("arte");
lista.add("bola");
lista.add("asa");
lista.add("buzo");
lista.add("coche");
lista.add("barco");
lista.add("duna");
// Obtenemos el stream
Stream<String> stream = lista.stream();
El objeto creado con stream() contiene una copia de todos los datos de la lista, no una referencia. Por lo tanto, los cambios que se hagan en el Stream no se van a reflejar en la lista original, que permanecerá intacta.