Inicializar un HashMap en Java

1. Información general

En este tutorial, aprenderemos sobre varias formas de inicializar un HashMap en Java.

Usaremos Java 8 y Java 9.

2. El inicializador estático para un HashMap estático

Podemos inicializar un HashMap usando un bloque de código estático :

public static Map articleMapOne; static { articleMapOne = new HashMap(); articleMapOne.put("ar01", "Intro to Map"); articleMapOne.put("ar02", "Some article"); }

La ventaja de este tipo de inicialización es que el mapa es mutable, pero solo funcionará para estático. En consecuencia, las entradas se pueden agregar y eliminar cuando sea necesario.

Sigamos adelante y probémoslo:

@Test public void givenStaticMap_whenUpdated_thenCorrect() { MapInitializer.articleMapOne.put( "NewArticle1", "Convert array to List"); assertEquals( MapInitializer.articleMapOne.get("NewArticle1"), "Convert array to List"); }

También podemos inicializar el mapa usando la sintaxis de doble llave:

Map doubleBraceMap = new HashMap() {{ put("key1", "value1"); put("key2", "value2"); }};

Tenga en cuenta que debemos tratar de evitar esta técnica de inicialización porque crea una clase adicional anónima en cada uso, contiene referencias ocultas al objeto que lo encierra y puede causar problemas de pérdida de memoria.

3. Uso de colecciones de Java

Si necesitamos crear un mapa inmutable singleton con una sola entrada, Collections.singletonMap () se vuelve muy útil:

public static Map createSingletonMap() { return Collections.singletonMap("username1", "password1"); }

Tenga en cuenta que el mapa aquí es inmutable, y si intentamos agregar más entradas, arrojará java.lang.UnsupportedOperationException.

También podemos crear un mapa vacío inmutable usando Collections.emptyMap ():

Map emptyMap = Collections.emptyMap();

4. El modo Java 8

En esta sección, veamos las formas de inicializar un mapa usando Java 8 Stream API.

4.1. Usando Collectors.toMap ()

Usemos una secuencia de una matriz de cadenas bidimensional y recopilemos en un mapa:

Map map = Stream.of(new String[][] { { "Hello", "World" }, { "John", "Doe" }, }).collect(Collectors.toMap(data -> data[0], data -> data[1]));

Observe que aquí el tipo de datos de la clave y el valor del mapa es el mismo.

Para hacerlo más genérico, tomemos la matriz de Objetos y realicemos la misma operación:

 Map map = Stream.of(new Object[][] { { "data1", 1 }, { "data2", 2 }, }).collect(Collectors.toMap(data -> (String) data[0], data -> (Integer) data[1]));

Como resultado, creamos un mapa de la clave como una Cadena y el valor como un Entero .

4.2. Uso de una secuencia de Map.Entry

Aquí usaremos las instancias de Map.Entry. Este es otro enfoque en el que tenemos diferentes tipos de claves y valores.

Primero, usemos la implementación SimpleEntry de la interfaz Entry :

Map map = Stream.of( new AbstractMap.SimpleEntry("idea", 1), new AbstractMap.SimpleEntry("mobile", 2)) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

Ahora creemos el mapa usando la implementación SimpleImmutableEntry :

Map map = Stream.of( new AbstractMap.SimpleImmutableEntry("idea", 1), new AbstractMap.SimpleImmutableEntry("mobile", 2)) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

4.3. Inicializar un mapa inmutable

En ciertos casos de uso, necesitamos inicializar un mapa inmutable. Esto se puede hacer envolviendo Collectors.toMap () dentro de Collectors.collectingAndThen () :

Map map = Stream.of(new String[][] { { "Hello", "World" }, { "John", "Doe" }, }).collect(Collectors.collectingAndThen( Collectors.toMap(data -> data[0], data -> data[1]), Collections:: unmodifiableMap));

Tenga en cuenta que debemos evitar el uso de dicha inicialización mediante Streams, ya que podría causar una gran sobrecarga de rendimiento y se crean muchos objetos basura solo para inicializar el mapa.

5. El método Java 9

Java 9 viene con varios métodos de fábrica en la interfaz de mapas que simplifican la creación e inicialización de mapas inmutables.

Sigamos adelante y analicemos estos métodos de fábrica.

5.1. Mapa de()

This factory method takes no argument, a single argument, and variable arguments:

Map emptyMap = Map.of(); Map singletonMap = Map.of("key1", "value"); Map map = Map.of("key1","value1", "key2", "value2");

Note that this method supports only a maximum of 10 key-value pairs.

5.2. Map.ofEntries()

It's similar to the Map.of() but has no limitations on the number of key-value pairs:

Map map = Map.ofEntries( new AbstractMap.SimpleEntry("name", "John"), new AbstractMap.SimpleEntry("city", "budapest"), new AbstractMap.SimpleEntry("zip", "000000"), new AbstractMap.SimpleEntry("home", "1231231231") );

Note that the factory methods produce immutable maps, hence any mutation will result in a UnsupportedOperationException.

Also, they do not allow null keys or duplicate keys.

Now if we need a mutable or growing map after initialization, we can create any of the implementations of the Map interface and pass these immutable maps in the constructor:

Map map = new HashMap ( Map.of("key1","value1", "key2", "value2")); Map map2 = new HashMap ( Map.ofEntries( new AbstractMap.SimpleEntry("name", "John"), new AbstractMap.SimpleEntry("city", "budapest")));

6. Using Guava

As we've looked into the ways of using core Java, let's move ahead and initialize a map using the Guava library:

Map articles = ImmutableMap.of("Title", "My New Article", "Title2", "Second Article");

Esto crearía un mapa inmutable y crearía uno mutable:

Map articles = Maps.newHashMap(ImmutableMap.of("Title", "My New Article", "Title2", "Second Article"));

El método ImmutableMap.of () también tiene versiones sobrecargadas que pueden tomar hasta 5 pares de parámetros clave-valor. Así es como se vería un ejemplo con 2 pares de parámetros:

ImmutableMap.of("key1", "value1", "key2", "value2");

7. Conclusión

En este artículo exploramos las diversas formas de inicializar un mapa , particularmente para crear mapas vacíos, únicos, inmutables y mutables. Como podemos ver, hay una gran mejora en este campo desde Java 9.

Como siempre, el código fuente de muestra se encuentra en el proyecto Github. Los ejemplos de Java 9 se encuentran aquí y el ejemplo de Guava aquí.