Filtrar Map a List en Java

En este artículo veremos dos formas de filtrar un Map a List en Java utilizando Stream API de Java. Primero veamos una introducción a esta característica.

Java 8 Stream API

Java 8 introduce una nueva abstracción llamada ‘Streams‘ mediante la cual da soporte a la programación funcional y nos permite, entre otras cosas, manipular datos de forma declarativa. Si estás usando una versión anterior de Java necesitarás actualizar a la versión 8 o superior para aprovechar las ventajas de Stream API, entre las cuales podemos enumerar las siguientes:

  • Codificación más compacta al permitir la manipulación de datos de forma declarativa. Con esto se logra código más fácil de leer: Stream API hace que el código sea más legible y fácil de entender, ya que permiten expresar operaciones complejas en una sola línea de código.
  • Capacidad para usar expresiones lambda y referencias de métodos: los Streams hacen uso de expresiones lambda y referencias de métodos que permiten un código más conciso y expresivo.
  • Soporte para procesamiento multi-thread en grandes volúmenes de datos.
  • Rendimiento mejorado: Stream API puede procesar datos de manera más eficiente que las colecciones tradicionales, lo que permite realizar operaciones más complejas en menos tiempo.
  • Escalabilidad y flexibilidad mejoradas: los Streams son altamente escalables, lo que permite que las operaciones se realicen en grandes conjuntos de datos y que las operaciones se adapten fácilmente a medida que crecen los conjuntos de datos.
  • Procesamiento paralelo: los Streams se pueden usar para realizar operaciones en paralelo, lo que permite mejorar el rendimiento y la escalabilidad.

En el siguiente gráfico se muestra cómo se estructura un típico procesamiento de datos usando Streams:

Filtrar Map a List usando Streams

Origen es la fuente que provee los datos destinados al procesamiento que se va a realizar y usualmente es una estructura de datos como maps, arrays, listas, etc. A partir de este origen se creará el Stream. Tener en cuenta que el Stream en sí mismo no es una estructura de datos, sino un flujo de datos cuya entrada es el origen antes mencionado.

Las Operaciones Intermedias se permiten cero o más y se debe tener en cuenta el orden. Por ejemplo, si se va a procesar un gran volúmen de datos, será conveniente aplicar primero un filtro a los efectos de reducir la cantidad de elementos antes de pasar a la siguiente operación intermedia en caso de existir, o a la operación terminal en su defecto. Esto redundará en una mejora de la performance.

Se permite sólo una Operación Terminal. En este ejemplo usamos forEach() para aplicar una misma función a cada elemento como mostrar el dato en pantalla.

Filtrar Map de String a List en Java

En el siguiente ejemplo vamos a obtener una lista filtrada a partir de un Map. Los pasos a seguir son:

  1. Usamos el método stream() para obtener el flujo de datos a partir de nuestro Map de origen.
  2. Aplicamos un filtro usando una expresión lambda para especificar el criterio a ser aplicado por el método filter(). Esta es nuestra Operación Intermedia.
  3. Agrupamos los datos obtenidos en una lista. Para hacer esto usamos el método collect(). Esta es nuestra Operación Terminal.
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class FilterMapExample1 {

	public static void main(String[] args) {
		Map<Integer, String> animales = new HashMap<Integer, String>();
		animales.put(1, "Tigre");
		animales.put(2, "Leopardo");
		animales.put(3, "Ballena");
		animales.put(4, "Orca");

		List<String> animales2 = animales.values().stream()
				.filter(a -> !"Orca".equals(a)).collect(Collectors.toList());
		
		animales2.forEach(System.out::println);
	}

}

La salida es:

Tigre
Leopardo
Ballena

Cómo aplicar el filtro en un Map de objetos

También es posible filtrar un Map que contiene objetos, aplicando el filtro sobre la propiedad que sea necesaria. Los pasos a seguir son los mismos que en el ejemplo anterior.

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class FilterMapExample2 {

	public static void main(String[] args) {
		Map<Integer, Animal> animales = new HashMap<Integer, Animal>();
		animales.put(1, new Animal("Tigre", "Felino"));
		animales.put(2, new Animal("Leopardo", "Felino"));
		animales.put(3, new Animal("Ballena", "Cetaceo"));
		animales.put(4, new Animal("Orca", "Cetaceo"));
		
		List<Animal> animales2 = animales.values().stream()
				.filter(a -> !"Cetaceo".equals(a.getCategoria())).collect(Collectors.toList());

		animales2.forEach(System.out::println);
	}

}

class Animal {
	
	private String especie;
	private String categoria;
	
	public Animal(String especie, String categoria) {
		this.especie = especie;
		this.categoria = categoria;
	}
	
	public String getEspecie() {
		return especie;
	}
	
	public void setEspecie(String especie) {
		this.especie = especie;
	}
	
	public String getCategoria() {
		return categoria;
	}
	
	public void setCategoria(String categoria) {
		this.categoria = categoria;
	}

	@Override
	public String toString() {
		return "-> Especie: " + this.especie + " | Categoria: " + this.categoria;
	}
}

La salida es:

-> Especie: Tigre | Categoria: Felino
-> Especie: Leopardo | Categoria: Felino

Conclusión

En este artículo hemos visto una introducción a Stream API y cómo aplicar esta característica de Java 8 para filtrar los datos de un Map y agrupar los resultados en una lista. Podrás profundizar en este tema en las referencias citadas a continuación.

Referencias


Te puede interesar:

Convertir Map a List en Java

En este artículo explicamos algunas formas sencillas de convertir un map a list en diferentes versiones de Java.

Seguir leyendo →

Cómo inicializar un Map en Java

En este artículo se explican diferentes formas de inicializar un java.util.Map en diferentes versiones de Java,

Seguir leyendo →

Palabras reservadas en Java

Las palabras reservadas en Java son un componente crucial de la sintaxis del lenguaje para formar los bloques básicos del lenguaje.

Seguir leyendo →