¿Cómo inicializar directamente un HashMap (de forma literal)?

Resuelto jens asked hace 13 años • 22 respuestas

¿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.

jens avatar Jul 24 '11 01:07 jens
Aceptado

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 testy test2serán iguales, solo que con diferentes formas de expresar el Mapa. El Map.ofmétodo está definido para hasta diez elementos en el mapa, mientras que el Map.ofEntriesmé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;
}
yankee avatar Jul 23 '2011 18:07 yankee

É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.offunciona para hasta 5 entradas. De lo contrario, utilice el constructor: fuente .

gregory561 avatar Jul 23 '2011 18:07 gregory561