Melhor maneira de criar um mapa vazio em Java

117

Eu preciso criar um mapa vazio.

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

O problema é que o código acima produz este aviso: Segurança de tipo: conversão não verificada de Mapa para HashMap

Qual é a melhor maneira de criar este mapa vazio?

JorgeO
fonte
Qual é o seu tipo declarado para fileParameters?
jjnguy
Você provavelmente obterá uma ClassCastException também.
Tom Hawtin - tackline
1
fileParameters deve ser um mapa e não um HashMap.
Steve Kuo

Respostas:

241

1) Se o mapa pode ser imutável:

Collections.emptyMap()

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

Você terá que usar o último às vezes, quando o compilador não puder descobrir automaticamente que tipo de mapa é necessário (isso é chamado de inferência de tipo ). Por exemplo, considere um método declarado assim:

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

Ao passar o mapa vazio diretamente para ele, você deve ser explícito sobre o tipo:

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

2) Se você precisa ser capaz de modificar o mapa, por exemplo:

new HashMap<String, String>()

(como tehblanx apontou )


Adendo : se o seu projeto usa Guava , você tem as seguintes alternativas:

1) Mapa imutável:

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

Concedido, nenhum grande benefício aqui comparado a Collections.emptyMap(). Do Javadoc :

Este mapa se comporta e tem um desempenho comparável Collections.emptyMap()e é preferível principalmente pela consistência e facilidade de manutenção do seu código.

2) Mapa que você pode modificar:

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

Mapscontém métodos de fábrica semelhantes para instanciar outros tipos de mapas também, como TreeMapou LinkedHashMap.


Atualização (2018) : No Java 9 ou mais recente, o código mais curto para criar um mapa vazio imutável é:

Map.of()

... usando os novos métodos de fábrica de conveniência da JEP 269 . 😎

Jonik
fonte
Na maioria dos casos, a inferência de tipo funciona (ou seja, map = Collections.emptyMap () funciona)
Sébastien RoccaSerra
Sim, verdade. Editei a resposta para ser um pouco mais abrangente.
Jonik
16

Collections.emptyMap ()

basszero
fonte
O problema é que este mapa só pode ser aplicado a um objeto Map e não a um HashMap
JorgeO
7
Você deve (geralmente) evitar declarar objetos de seus tipos específicos e usar a interface (ou pai abstrato). Tente evitar "HashMap <String, String> foo;" e use "Map <String, String> foo;" em vez disso
TofuBeer
10

Se você precisa de uma instância de HashMap, a melhor maneira é:

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

Como Map é uma interface, você precisa escolher alguma classe que o instancie se quiser criar uma instância vazia. HashMap parece tão bom quanto qualquer outro - apenas use isso.

AndreiM
fonte
7

Ou Collections.emptyMap(), se a inferência de tipo não funcionar no seu caso,
Collections.<String, String>emptyMap()

Peter Štibraný
fonte
2

Uma vez que em muitos casos um mapa vazio é usado para design de segurança nula, você pode utilizar o nullToEmptymétodo utilitário:

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()
    }
  }

}  

Da mesma forma para conjuntos:

class SetUtils {

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

}

e listas:

class ListUtils {

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

}
Vitalii Fedorenko
fonte