1. Elementos de recogida

Finalmente, hemos llegado al método más interesante de la Streamclase, el collect()método. Se utiliza para pasar de flujos a nuestras colecciones familiares: List<T>, Set<T>, Map<T, R>y otras.

El collect()método toma un collectorobjeto especial como argumento. Este objeto lee todos los datos del flujo, los convierte en un tipo específico de colección y los devuelve. Y luego el propio método de recopilación devuelve esta colección.

Todo esto se hace de una manera bastante hábil: el collectortipo de objeto es Collector<T, A, R>. Como puede ver, tiene tres parámetros de tipo. El último parámetro de tipo ( R) suele ser un tipo como List<T>. Esto significa que el compilador puede usar este tipo para determinar el tipo de devolución correcto para el collect()método en sí.

Espero que no estés demasiado confundido. En cualquier caso, no es necesario que cree objetos Collector usted mismo. Los objetos preparados devueltos por los métodos estáticos de la Collectorsclase serán suficientes.

Clase de coleccionistas

La Collectorsclase tiene varios métodos estáticos que devuelven objetos de colección listos para usar, algo para cada ocasión. Aquí consideraremos los más importantes.

toList()
Un objeto que convierte un flujo en una lista ( List<T>)
toSet()
Un objeto que convierte un flujo en un conjunto ( Set<T>)
toMap()
Un objeto que convierte un flujo en un mapa ( Map<K, V>)
joining()
Concatena los elementos de una secuencia en una sola cadena
mapping()
Convierte los elementos de una cadena en unMap<K, V>
groupingBy()
Agrupa los elementos y devuelveMap<K, V>

2. Convertir un flujo en una lista

El siguiente es un ejemplo típico de trabajar con una secuencia y convertir el resultado en una lista

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");

List<String> result = list.stream()
   .filter( s -> Character.isUpperCase(s.charAt(0)) )
   .collect( Collectors.toList() );

Tenemos una transmisión de la colección. Luego obtuvimos una nueva secuencia al retener solo las cadenas cuyo primer carácter está en mayúscula. Luego, todos los datos de ese flujo se recopilan en una colección, que luego se devuelve.



3. Convertir una secuencia en un conjunto

El siguiente es un ejemplo típico de trabajar con una secuencia y convertir el resultado en un conjunto

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");

Set<String> result = list.stream()
   .filter( s -> Character.isUpperCase(s.charAt(0)) )
   .collect( Collectors.toSet() );

Todo es muy similar al código para convertir un flujo en un List, solo que usamos un objeto colector diferente, que es devuelto por el toSet()método.



4. Convertir una secuencia en un mapa

Pero convertir una secuencia en un mapa es un poco más difícil. Cada entrada en un mapa consta de dos elementos: una clave y un valor. Necesitamos averiguar cómo definiremos la clave y el valor para cada elemento en la secuencia.

Ejemplo:

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "a=2", "b=3", "c=4", "d==3");

Map<String, String> result = list.stream()
   .map( e -> e.split("=") )
   .filter( e -> e.length == 2 )
   .collect( Collectors.toMap(e -> e[0], e -> e[1]) );

Echemos un vistazo a lo que está pasando aquí.

En la primera línea, usamos map(...)para convertir cada cadena en una matriz de cadenas. Usando el método de división, dividimos cada cadena en dos partes.

En la segunda línea, pasamos al filter()método solo aquellas matrices que contienen exactamente dos elementos. La d==3cadena se divide en una matriz de tres elementos, que no coincide con el filtro.

Y finalmente, en la última línea, convertimos la secuencia en un archivo Map<String, String>. Se pasan dos funciones al toMap()método. Para cada elemento de la secuencia, la primera función debe devolver la clave y la segunda el valor .

El primer elemento de cada matriz ("a", "b", "c") será nuestra clave, y el segundo elemento de cada matriz ("2", "3", "4") será nuestro valor.



5. Convertir un flujo en una cadena

Otro objeto de colección interesante es devuelto por Collectors.joining(). Convierte todos los elementos de una secuencia Stringy los concatena en una sola cadena. Ejemplo

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "a=2", "b=3", "c=4", "d==3");
String result = list.stream().collect( Collectors.joining(", ") );