Como filtrar Optional en streams de Java


En este post vamos a ver las distintas opciones para filtrar los valores no-empty de un Stream de Optional.

Para el ejemplo, usaremos la siguiente lista donde se puede ver que tenemos varios valores Optional.empty():

List<Optional<Integer>> numeros = Arrays.asList(
		Optional.of(1),
		Optional.empty(),
		Optional.of(2),
		Optional.of(3),
		Optional.empty(),
		Optional.of(4));

Filtrando Optional usando filter + map

Esta opción es la más intuitiva. Primero aplicamos un filter indicando que solo queremos los Optional que tengan valor, y a continuación aplicamos un map para obtener el valor correspondiente:

List<Integer> numerosSinOptional = numeros.stream()
		.filter(Optional::isPresent)
		.map(Optional::get)
		.collect(Collectors.toList());

Filtrando Optional usando Optional.stream y flatMap

Gracias a la operación Optional.stream (este método solo está disponible si estamos usando Java 9 o superior) convierte nuestro Optional en un Stream, devolviendo un Stream.empty() en caso de ser un Optional.empty(). Y con la operación flatMap pasamos de un Stream de Streams a un único Stream. Por tanto, lo que estamos haciendo es uniendo todos los streams que genera cada Optional::stream, y el propio flatMap, en caso de encontrarse Stream.empty ya no lo añade al Stream final. Por tanto, lo que antes eran 2 operaciones en el Stream ahora se traduce en una única operación:

List<Integer> numerosSinOptional = numeros.stream()
		.flatMap(Optional::stream)
		.collect(Collectors.toList());

Aunque esta operación pueda parecer menos intuitiva, resulta ser la opción más óptima.

Avatar
Actualizado el 22 de noviembre de 2022
Comparte este artículo:
TwitterFacebookLinked In
Icon