Esto es una traducción del siguiente artículo para mi uso: https://dzone.com/articles/how-to-use-map-filter-collect-of-stream-in-java-8
La función map() es un método de la clase Stream que representa el concepto de programación funcional. Simplificando, el map() se usa para transformar un objeto en otro aplicando una función.
Esta es la razón por la que Stream.map(Function mapper) tiene una Function como argumento. Por ejemplo, usando la Function map() puedes convertir una lista de String en una lista de Integer aplicando el método Integer.valueOf() a cada String en la lista de entrada.
Todo lo que necesitas es una función de mapeo para convertir un objeto en el otro. Entonces, la función map() hará la transformación para tí. Es también una operación Stream intermedia, lo que significa que puedes llamar a otros métodos Stream, como filter o collect para crear una cadena de transformaciones.
El método filter, como su nombre indica, filtra elementos basándose en la condición que le das. Por ejemplo, si tu lista contiene números y sólo quieres números pares, puedes usar el método filter para seleccionar sólo los números divisibles entre dos
El método filter selecciona elementos basándose en la condición que le proporcionas. Es por eso que filter acepta un Predicate object, que proporciona la función que es aplicada a la condición. Si la la condición se cumple, el objeto es seleccionado. Si no se cumple será ignorada
Igual que map, la operación filter es una operación intermedia, lo que significa que puedes llamar otros métodos Stream tras llamar al filter. El método filter() también es lazy (perezoso), lo que significa que no será evaluado hasta que se realice una llamada a un método reduction, como collect, y se detendrá tan pronto como alcance su objetivo.
Cómo usar Map y Filter en Java 8
Se necesita un buen ejemplo para entender cualquier concepto nuevo. String e Integer son los tipos de dato más comunes en Java, he elegido un ejemplo que es simple e interesante.
Teniendo la lista de números definidos como String {«1», «2», «3», «4», «5», «6»}. Quiero procesar la lista y conseguir otra lista de tipo Integer con los números.
Para conseguir los números, primero necesito convertir la List<String> a List<Integer>. Para hacerlo, puedo usar el método map() de la clase java.util.Stream. Pero antes necesitamos un Stream como map() como se define en la clase java.util.stream.
Esto no es difícil, puedes conseguir un stream a partir de cualquier collection (List, Set…) llamando al método stream(), que está definido en la interface java.util.Collection
El método map(Function mapper) toma una Function, técnicamente hablando, un objeto del tipo java.util.Function. Esta Function es aplicada a cada elemento del Stream para convertirlo en el tipo que queremos
Como necesitamos convertir un String a Integer, podemos pasar los métodos Integer.parseInt() o Integer.valueOf() a la función map().
Se elige el método valueOf() por rendimiento y caché.
El map() devolverá un Stream de Integer que contiene tanto los números pares e impares. Para seleccionar sólo los pares podemos usar el método filter().
Para eso usaremos un object predicate que es técnicamente una Function que convierte un objeto a Boolean. Pasamos un objeto y devuelve true o false. El filter, usa esa información para incluir el objeto en el stream resultado.
Para incluir sólo los números pares llamamos a filter(number -> number%2==0), lo que significa que cada número será dividido entre dos y si no hay resto, será elegido.
Ya casi estamos. Pero, hasta aquí sólo tenemos el Stream de números pares, no la List de pares Integer que es lo que necesitamos.
Como necesitamos una List ejecutamos collect(Collectors.toList()), lo que acumula todos los números pares en una List y la devuelve.
Cómo sabe que tiene que devolver una List? Recuperamos esa información por Type inference (Inferencia de tipo), porque hemos definido la lista como List<Integer>

Aquí tenemos el código Java que implementa lo que hemos explicado en la sección superior. Este código es ejecutable
Puedes probar usando más Functions map() o más filter() para hacer la composición más larga y complicada. Puedes usar el método collect() para recuperar el resultado en una List, Set o Map o cualquier otra collection.
package tool;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
*
* A simple Java Program to demonstrate how to use map and filter method Java 8.
* In this program, we'll convert a list of String into a list of Integer and
* then filter all even numbers.
*/
public class Hello {
public static void main(String[] args) {
List<String> numbers = Arrays.asList("1", "2", "3", "4", "5", "6");
System.out.println("original list: " + numbers);
List<Integer> even = numbers.stream()
.map(s -> Integer.valueOf(s))
.filter(number -> number % 2 == 0)
.collect(Collectors.toList());
System.out.println("processed list, only even numbers: " + even);
}
}
Output
original list: [1, 2, 3, 4, 5, 6]
the processed list, only even numbers: [2, 4, 6]
Se puede ver que la lista original contiene números desde 1 a 6 y que la lista filtrada sólo contiene los números pares, 2, 4 y 6
La parte más importante del código en este ejemplo es la compuesta por las cuatro líneas siguientes

El código empieza con un map, después un filter y finalmente un collect. Importa el orden? Sí, importa.
Como nuestro filtro necesita de un valor int antes necesitamos convertir el Stream de String en un Stream de Integer. Por eso llamamos a la Function map() primero.
Una vez que tenemos el Stream de Integer, podemos realizar la operación que nos encuentra los números pares y pasar esa condición al filter.