Escribir código eficiente en Java es una habilidad esencial para cualquier programador. Una de las tareas más importantes es iterar un Map, que se utiliza para almacenar pares clave-valor. En este artículo vamos a repasar algunas formas de iterar a través de Map en Java.
La forma de iterar a través de una colección es parte de nuestra rutina de programación y en general es bien conocida, pero a diferencia de otras colecciones, no podemos iterar a través de HashMap directamente, necesitamos obtener el conjunto de claves o el conjunto de entradas para iterar.
Obteniendo el Entry Set del Map e iterarlo con un For-Each
La forma más habitual de iterar un Map es utilizar el método entrySet() para obtener la colección de ítems y luego iterarla.
Recordemos que un HashMap almacena los datos en forma de pares Clave/Valor y a su vez, cada par se almacena en una instancia de la clase Map.Entry.
El método entrySet() simplemente retorna un Set con las entradas del HashMap, permitiéndonos de esta forma trabajar directamente sobre el conjunto de datos.
A continuación se muestra como iterar el contenido del HashMap recuperando las entradas con el método entrySet() e iterándola con un bucle For-Each. En cada iteración accedemos al par Clave/Valor mediante los métodos getKey() y getValue() de la clase Map.Entry.
import java.util.HashMap;
import java.util.Map;
public class IterarMapEjemplo1 {
public static void main(String[] args) {
Map<Integer, String> map = new HashMap<Integer, String>();
map.put(1, "Mar");
map.put(2, "Lago");
map.put(3, "Rio");
map.put(4, "Arroyo");
for (Map.Entry<Integer, String> entry : map.entrySet()) {
System.out.println("-> " + entry.getKey() + " : " + entry.getValue());
}
}
}
Salida:
-> 1 : Mar -> 2 : Lago -> 3 : Rio -> 4 : Arroyo
Iterar un Map en Java utilizando una expresión lambda
Las expresiones lambda se utilizan en Java para implementar interfaces funcionales. Nos permite lograr una implementación más simple y compacta donde si en su lugar usáramos, por ejemplo, clases anónimas, obtendríamos un código más engorroso.
Una expresión lambda tiene la siguiente estructura:
Entonces, una expresión lambda se compone de:
- Una lista de parámetros (puede estar vacía)
- Flecha (Arrow token)
- Cuerpo que contiene las expresiones
Si estamos trabajando con Java 8 o superior, podemos simplificar la forma de iterar utilizando el método Map.forEach(BiConsumer action), e implementando el action correspondiente con una expresión lambda.
import java.util.HashMap;
import java.util.Map;
public class IterarMapEjemplo2 {
public static void main(String[] args) {
Map<Integer, String> map = new HashMap<Integer, String>();
map.put(1, "Mar");
map.put(2, "Lago");
map.put(3, "Rio");
map.put(4, "Arroyo");
map.forEach((k, v) -> {
System.out.println("Key : " + k + " Value : " + v);
});
}
}
Salida:
Key : 1 Value : Mar Key : 2 Value : Lago Key : 3 Value : Rio Key : 4 Value : Arroyo
Iterar un Map en Java utilizando Entry Set y forEach
Este ejemplo es muy similar al anterior, pero con una diferencia. En este caso no utilizamos el método forEach() de HashMap, sino el del Set de ítems (obtenido con el método entrySet()).
Notar que ahora la expresión lambda recibe un objeto (Map.Entry), y en el cuerpo de la expresión obtenemos la Clave y Valor de cada ítem con los métodos getter correspondientes.
import java.util.HashMap;
import java.util.Map;
public class IterarMapEjemplo3 {
public static void main(String[] args) {
Map<Integer, String> map = new HashMap<Integer, String>();
map.put(1, "Mar");
map.put(2, "Lago");
map.put(3, "Rio");
map.put(4, "Arroyo");
map.entrySet().forEach(entry -> {
System.out.println("Key : " + entry.getKey() + " Value : " + entry.getValue());
});
}
}
Salida:
Key : 1 Value : Mar Key : 2 Value : Lago Key : 3 Value : Rio Key : 4 Value : Arroyo
Obteniendo las keys e iterarlas utlizando un For-Each
Otra opción es utilizar el método Map.keySet() para obtener un Set con las keys contenidas en el Map, y luego utilizar un For-Each para realizar la iteración.
import java.util.HashMap;
import java.util.Map;
public class IterarMapEjemplo4 {
public static void main(String[] args) {
Map<Integer, String> map = new HashMap<Integer, String>();
map.put(1, "Mar");
map.put(2, "Lago");
map.put(3, "Rio");
map.put(4, "Arroyo");
for (Integer key : map.keySet()) {
System.out.println("-> key: " + key + " | value: " + map.get(key));
}
}
}
Salida:
-> key: 1 | value: Mar -> key: 2 | value: Lago -> key: 3 | value: Rio -> key: 4 | value: Arroyo
Iterar un Map en Java usando Stream API
En Java 8 o superior tenemos la posibilidad de utilizar Stream API que le permite, entre otras cosas, procesar datos de forma declarativa. El potencial de Stream API puede ser mejor aprovechado con un procesamiento más elaborado.
import java.util.HashMap;
import java.util.Map;
public class IterarMapEjemplo5 {
public static void main(String[] args) {
Map<Integer, String> map = new HashMap<Integer, String>();
map.put(1, "Mar");
map.put(2, "Lago");
map.put(3, "Rio");
map.put(4, "Arroyo");
map.entrySet().stream().forEach(e -> {
System.out.println("-> key: " + e.getKey() + " | value: " + e.getValue());
});
}
}
Salida:
-> key: 1 | value: Mar -> key: 2 | value: Lago -> key: 3 | value: Rio -> key: 4 | value: Arroyo
Conclusión
Como vimos, Java ofrece múltiples formas de iterar el contenido de una estructura Map, siendo recomendable, en caso de estar utilizando Java 8 o superior, la utilización de Streams y expresiones lambda por razones de eficiencia además de obtener un código más compacto.
Te puede interesar
Cómo ordenar un Map en Java
En este artículo explicamos cómo ordenar los ítems de un Map en Java por la clave o el valor de los ítems.
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.