Meilleur moyen de créer une carte vide en Java

117

J'ai besoin de créer une carte vide.

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

Le problème est que le code ci-dessus génère cet avertissement: Sécurité de type: Cast non coché de Map vers HashMap

Quelle est la meilleure façon de créer cette carte vide?

JorgeO
la source
Quel est votre type déclaré pour fileParameters?
jjnguy
Vous obtiendrez probablement aussi une ClassCastException.
Tom Hawtin - tackline
1
fileParameters doit être un Map et non un HashMap.
Steve Kuo

Réponses:

241

1) Si la carte peut être immuable:

Collections.emptyMap()

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

Vous devrez parfois utiliser ce dernier lorsque le compilateur ne peut pas automatiquement déterminer le type de carte nécessaire (cela s'appelle l' inférence de type ). Par exemple, considérons une méthode déclarée comme ceci:

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

Lorsque vous lui passez directement la carte vide, vous devez être explicite sur le type:

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

2) Si vous avez besoin de pouvoir modifier la carte, alors par exemple:

new HashMap<String, String>()

(comme l' a souligné tehblanx )


Addendum : Si votre projet utilise Guava , vous avez les alternatives suivantes:

1) Carte immuable:

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

Certes, pas de gros avantages ici par rapport à Collections.emptyMap(). Depuis le Javadoc :

Cette carte se comporte et fonctionne de manière comparable à Collections.emptyMap(), et est préférable principalement pour la cohérence et la maintenabilité de votre code.

2) Carte que vous pouvez modifier:

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

Mapscontient des méthodes d'usine similaires pour instancier également d'autres types de cartes, telles que TreeMapou LinkedHashMap.


Mise à jour (2018) : Sur Java 9 ou plus récent, le code le plus court pour créer une carte vide immuable est:

Map.of()

... en utilisant les nouvelles méthodes d'usine de confort de JEP 269 . 😎

Jonik
la source
Dans la plupart des cas, l'inférence de type fonctionne (c.-à-d. Map = Collections.emptyMap () fonctionne)
Sébastien RoccaSerra
Ouais vrai. J'ai édité la réponse pour être un peu plus complète.
Jonik
16

Collections.emptyMap ()

basszero
la source
Le problème était que cette carte ne peut être appliquée qu'à un objet Map et non un HashMap
JorgeO
7
Vous devriez (généralement) éviter de déclarer des objets de leurs types spécifiques et utiliser plutôt l'interface (ou le parent abstrait). Essayez d'éviter "HashMap <String, String> foo;" et utilisez "Map <String, String> foo;" à la place
TofuBeer
10

Si vous avez besoin d'une instance de HashMap, le meilleur moyen est:

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

Puisque Map est une interface, vous devez choisir une classe qui l'instancie si vous souhaitez créer une instance vide. HashMap semble aussi bon que n'importe quel autre - alors utilisez-le.

AndreiM
la source
7

Soit Collections.emptyMap(), soit si l'inférence de type ne fonctionne pas dans votre cas,
Collections.<String, String>emptyMap()

Peter Štibraný
la source
2

Étant donné que dans de nombreux cas, une carte vide est utilisée pour une conception de sécurité nulle, vous pouvez utiliser la nullToEmptyméthode utilitaire:

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 même pour les ensembles:

class SetUtils {

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

}

et listes:

class ListUtils {

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

}
Vitalii Fedorenko
la source