¿Cómo inicializar directamente un HashMap (de forma literal)?
¿Existe alguna forma de inicializar un Java HashMap como este?:
Map<String,String> test =
new HashMap<String, String>{"test":"test","test":"test"};
¿Cuál sería la sintaxis correcta? No he encontrado nada al respecto. es posible? Estoy buscando la forma más corta/rápida de poner algunos valores "finales/estáticos" en un mapa que nunca cambien y que se conozcan de antemano al crear el mapa.
Todas las versiones
En caso de que necesite una sola entrada: hay Collections.singletonMap("key", "value")
.
Para Java versión 9 o superior:
Sí, esto es posible ahora. En Java 9 se han agregado un par de métodos de fábrica que simplifican la creación de mapas:
// this works for up to 10 elements:
Map<String, String> test1 = Map.of(
"a", "b",
"c", "d"
);
// this works for any number of elements:
import static java.util.Map.entry;
Map<String, String> test2 = Map.ofEntries(
entry("a", "b"),
entry("c", "d")
);
En el ejemplo anterior, ambos test
y test2
serán iguales, solo que con diferentes formas de expresar el Mapa. El Map.of
método está definido para hasta diez elementos en el mapa, mientras que el Map.ofEntries
método no tendrá tal límite.
Tenga en cuenta que en este caso el mapa resultante será un mapa inmutable. Si desea que el mapa sea mutable, puede copiarlo nuevamente, por ejemplo usando mutableMap = new HashMap<>(Map.of("a", "b"));
. También tenga en cuenta que en este caso las claves y los valores no deben ser null
.
(Ver también JEP 269 y el Javadoc )
Para hasta Java versión 8:
No, tendrás que agregar todos los elementos manualmente. Puedes usar un inicializador en una subclase anónima para acortar un poco la sintaxis:
Map<String, String> myMap = new HashMap<String, String>() {{
put("a", "b");
put("c", "d");
}};
Sin embargo, la subclase anónima puede introducir comportamientos no deseados en algunos casos. Esto incluye por ejemplo:
- Genera una clase adicional que aumenta el consumo de memoria, el consumo de espacio en disco y el tiempo de inicio.
- En el caso de un método no estático: contiene una referencia al objeto al que se invocó el método de creación. Eso significa que el objeto de la clase externa no puede ser recolectado como basura mientras todavía se hace referencia al objeto de mapa creado, lo que bloquea la memoria adicional.
El uso de una función para la inicialización también le permitirá generar un mapa en un inicializador, pero evita efectos secundarios desagradables:
Map<String, String> myMap = createMap();
private static Map<String, String> createMap() {
Map<String,String> myMap = new HashMap<String,String>();
myMap.put("a", "b");
myMap.put("c", "d");
return myMap;
}
Ésta es una forma.
Map<String, String> h = new HashMap<String, String>() {{
put("a","b");
}};
Sin embargo, debe tener cuidado y asegurarse de comprender el código anterior (crea una nueva clase que hereda de HashMap). Por lo tanto, deberías leer más aquí: http://www.c2.com/cgi/wiki?DoubleBraceInitialization , o simplemente usar Guava:
Map<String, Integer> left = ImmutableMap.of("a", 1, "b", 2, "c", 3);
ImmutableMap.of
funciona para hasta 5 entradas. De lo contrario, utilice el constructor: fuente .