En ocasiones es buena práctica contar con datos de solo lectura para ser consultados por los diferentes procesos de la aplicación. En estos casos podemos crear un map de solo lectura o Mapas inmutables. El uso de estos últimos tiene varios beneficios como uso reducido de memoria, acceso a datos más rápido y mayor seguridad para subprocesos (thread-safe).
Crear un Map de sólo lectura en Java a partir de uno modificable.
El método Collections.unmodifiableMap(map) permite crear un Map inmodificable a partir de uno modificable. Esto se logra ‘envolviendo’ al Map original con una nueva instancia que restringe la posibilidad de editar su contenido.
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public class InmutableMapEjemplo1 {
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<Integer, String> umap = Collections.unmodifiableMap(map);
umap.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
Si se intenta modificar el Map de solo lectura se obtendrá una java.lang.UnsupportedOperationException, pero se debe tener en cuenta que si se modifican o agregan nuevos datos en el Map original (que es editable), estos cambios se verán reflejados en el Map de solo lectura.
Crear un Map de sólo lectura con una única entrada.
Podemos restringir totalmente la posibilidad de alteración de los datos creando un Map inmutable. Una forma de hacer esto es utilizando el método Collections.singletonMap(key, value).
import java.util.Collections;
import java.util.Map;
public class InmutableMapEjemplo3 {
public static void main(String[] args) {
Map<Integer, String> map = Collections.singletonMap(1, "Geografia");
map.forEach((k, v) -> System.out.println("-> key: " + k + " - value: " + v));
}
}
Salida:
-> key: 1 - value: Geografia
Utilizando los Factory Methods de la interfaz java.util.Map (Java 9).
Si estamos trabajando con Java 9 podemos utilizar:
- Map.of(key, value, …): retorna un java.util.Map inmutable que contiene los pares key/value pasados por parámetro. Este método está sobrecargado para recibir hasta 10 pares key/value.
- Map.ofEntries(…entries): retorna un java.util.Map inmutable que contiene los pares key/value de las entradas pasadas por parámetro. En este caso no hay limitación en la cantidad de entradas.
import java.util.Map;
public class InmutableMapEjemplo4 {
public static void main(String[] args) {
Map<Integer, String> map = Map.of(1,"Geografia", 2, "Fisica");
map.forEach((k, v) -> System.out.println("-> key: " + k + " - value: " + v));
}
}
Salida:
-> key: 1 - value: Geografia -> key: 2 - value: Fisica
import java.util.AbstractMap;
import java.util.Map;
public class InmutableMapEjemplo5 {
public static void main(String[] args) {
Map<Integer, String> map = Map.ofEntries(
new AbstractMap.SimpleEntry<Integer, String>(1, "Mar"),
new AbstractMap.SimpleEntry<Integer, String>(2, "Lago"),
new AbstractMap.SimpleEntry<Integer, String>(3, "Rio"),
new AbstractMap.SimpleEntry<Integer, String>(4, "Arroyo")
);
map.forEach((k, v) -> System.out.println("-> key: " + k + " - value: " + v));
}
}
Salida:
-> key: 4 - value: Arroyo -> key: 3 - value: Rio -> key: 2 - value: Lago -> key: 1 - value: Mar
Conclusión
En este artículo hemos visto que hay varias formas de crear un Map de solo lectura en Java. El uso de Collections.unmodifiableMap(Map<K, V>) proporciona una forma de crear un Map de solo lectura a partir de uno existente, mientras que Collections.singletonMap(K key, V value) instanciar un Map con una sola entrada. Los Factory Methods de Java 9 proporcionan una forma más concisa y legible de crearlo con un número arbitrario de entradas. La elección de qué método usar depende de su caso de uso específico y su preferencia personal.
Te puede interesar
Filtrar Map a List en Java
En este artículo explicamos diferentes formas de filtrar los valores de un map y pasarlos a una List en Java.