La mejor manera de crear un mapa vacío en Java


117

Necesito crear un mapa vacío.

if (fileParameters == null)
    fileParameters = (HashMap<String, String>) Collections.EMPTY_MAP;

El problema es que el código anterior produce esta advertencia: Tipo de seguridad: Transmitir sin marcar de Map a HashMap

¿Cuál es la mejor forma de crear este mapa vacío?


¿Cuál es su tipo declarado para fileParameters?
jjnguy

Probablemente también obtendrá una ClassCastException.
Tom Hawtin - tackline

1
fileParameters debe ser un mapa y no un HashMap.
Steve Kuo

Respuestas:


241

1) Si el mapa puede ser inmutable:

Collections.emptyMap()

// or, in some cases:
Collections.<String, String>emptyMap()

Tendrá que usar este último a veces cuando el compilador no pueda determinar automáticamente qué tipo de mapa se necesita (esto se llama inferencia de tipo ). Por ejemplo, considere un método declarado así:

public void foobar(Map<String, String> map){ ... }

Al pasar el Mapa vacío directamente a él, debe ser explícito sobre el tipo:

foobar(Collections.emptyMap());                 // doesn't compile
foobar(Collections.<String, String>emptyMap()); // works fine

2) Si necesita poder modificar el Mapa, por ejemplo:

new HashMap<String, String>()

(como señaló tehblanx )


Anexo : Si su proyecto utiliza Guayaba , tiene las siguientes alternativas:

1) Mapa inmutable:

ImmutableMap.of()
// or:
ImmutableMap.<String, String>of()

Por supuesto, no hay grandes beneficios aquí en comparación con Collections.emptyMap(). Desde el Javadoc :

Este mapa se comporta y funciona de manera comparable Collections.emptyMap()y es preferible principalmente por la coherencia y el mantenimiento de su código.

2) Mapa que puedes modificar:

Maps.newHashMap()
// or:
Maps.<String, String>newHashMap()

Mapscontiene métodos de fábrica similares para crear instancias de otros tipos de mapas, como TreeMapo LinkedHashMap.


Actualización (2018) : en Java 9 o posterior, el código más corto para crear un mapa vacío inmutable es:

Map.of()

... utilizando los nuevos métodos de fábrica de conveniencia de JEP 269 . 😎


En la mayoría de los casos, la inferencia de tipos funciona (es decir, map = Collections.emptyMap () funciona)
Sébastien RoccaSerra

Si cierto. Edité la respuesta para que fuera un poco más completa.
Jonik

16

El problema era que este mapa solo se puede aplicar a un objeto Map, no a un HashMap
JorgeO

7
Debería (generalmente) evitar declarar objetos de sus tipos específicos y usar la interfaz (o padre abstracto) en su lugar. Intente evitar "HashMap <String, String> foo;" y use "Map <String, String> foo;" en su lugar
TofuBeer


10

Si necesita una instancia de HashMap, la mejor manera es:

fileParameters = new HashMap<String,String>();

Dado que Map es una interfaz, debe elegir alguna clase que la instancia si desea crear una instancia vacía. HashMap parece tan bueno como cualquier otro, así que utilícelo.


7

O bien Collections.emptyMap(), o si la inferencia de tipos no funciona en su caso,
Collections.<String, String>emptyMap()


2

Dado que en muchos casos se utiliza un mapa vacío para un diseño seguro para nulos, puede utilizar el nullToEmptymétodo de utilidad:

class MapUtils {

  static <K,V> Map<K,V> nullToEmpty(Map<K,V> map) {
    if (map != null) {
      return map;
    } else {
       return Collections.<K,V>emptyMap(); // or guava ImmutableMap.of()
    }
  }

}  

De manera similar para los conjuntos:

class SetUtils {

  static <T> Set<T> nullToEmpty(Set<T> set) {
    if (set != null) {
      return set;
    } else {
      return Collections.<T>emptySet();
    }
  }

}

y listas:

class ListUtils {

  static <T> List<T> nullToEmpty(List<T> list) {
    if (list != null) {
      return list;
    } else {
      return Collections.<T>emptyList();
    }
  }

}

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.