2009-03-11 7 views
73

Je dois créer une carte vide.Meilleure façon de créer une carte vide en Java

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

Le problème est que le code ci-dessus produit cet avertissement: sécurité Type: Carte de Décoché coulé à hashmap

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

+0

Quel est votre type déclaré pour les paramètres de fichier? – jjnguy

+0

Vous obtiendrez probablement une exception ClassCastException. –

+1

fileParameters doit être une carte et non une HashMap. –

Répondre

143

1) Si la carte peut être immuable:

Collections.emptyMap(); 

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

Vous Il faudra parfois utiliser ce dernier lorsque le compilateur ne pourra pas déterminer automatiquement quel type de carte est nécessaire (cela s'appelle type inference). Par exemple, envisager une méthode déclarée comme ceci:

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

Lors du passage de la carte vide directement, vous devez être explicite sur le type:

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

2) Si vous devez être en mesure de modifier la carte, par exemple:

new HashMap<String, String>(); 

(comme tehblanx pointed out)


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

1) carte Immuable:

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

Attribuées, pas de gros avantages ici par rapport à Collections.emptyMap(). From the Javadoc:

Cette carte se comporte et exécute à Collections.emptyMap() comparable, 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(); 

Maps contient des méthodes d'usine similaires pour instancier d'autres types de cartes aussi bien, comme TreeMap ou LinkedHashMap.

+0

Dans la plupart des cas, l'inférence de type fonctionne (ie map = Collections.emptyMap() fonctionne) –

+0

Ouais, vrai. J'ai édité la réponse pour être un peu plus complet. – Jonik

9

Si vous avez besoin d'une instance de HashMap, la meilleure façon est:

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

Depuis Carte est une interface, vous devez choisir une classe qu'il instancie si vous voulez créer une instance vide. HashMap semble aussi bon que n'importe quel autre - alors utilisez-le.

13
+0

Le problème était que cette carte ne peut être appliquée qu'à un objet Map pas à un HashMap – JorgeO

+6

Vous devriez (généralement) éviter de déclarer des objets de leurs types spécifiques et utiliser l'interface (ou le parent abstrait) à la place. Essayez d'éviter "HashMap foo;" et utilisez "Map foo;" à la place – TofuBeer

+0

+1 TofuBeer (si seulement je pouvais) –

6

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

1

Etant donné que dans de nombreux cas, une carte vide est utilisé pour la conception null-safe, vous pouvez utiliser la méthode utilitaire nullToEmpty:

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 jeux:

class SetUtils { 

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

} 

et les listes:

class ListUtils { 

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

} 
Questions connexes