Il modo migliore per creare una mappa vuota in Java


117

Devo creare una mappa vuota.

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

Il problema è che il codice precedente produce questo avviso: Sicurezza dei tipi: cast non controllato da Map a HashMap

Qual è il modo migliore per creare questa mappa vuota?


Qual è il tuo tipo dichiarato per fileParameters?
jjnguy

Probabilmente avrai anche un'eccezione ClassCastException.
Tom Hawtin - tackline

1
fileParameters dovrebbe essere una mappa e non una HashMap.
Steve Kuo

Risposte:


241

1) Se la mappa può essere immutabile:

Collections.emptyMap()

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

Dovrai usare quest'ultimo a volte quando il compilatore non riesce a capire automaticamente che tipo di mappa è necessario (questo è chiamato inferenza del tipo ). Ad esempio, considera un metodo dichiarato in questo modo:

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

Quando passi la mappa vuota direttamente ad essa, devi essere esplicito sul tipo:

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

2) Se è necessario essere in grado di modificare la mappa, ad esempio:

new HashMap<String, String>()

(come ha sottolineato tehblanx )


appendice : se il tuo progetto utilizza Guava , hai le seguenti alternative:

1) Mappa immutabile:

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

Certo, nessun grande vantaggio qui rispetto a Collections.emptyMap() . Dal Javadoc :

Questa mappa si comporta e si comporta in modo simile a Collections.emptyMap() ed è preferibile principalmente per la coerenza e la manutenibilità del codice.

2) Mappa che puoi modificare:

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

Mapscontiene metodi di fabbrica simili per istanziare anche altri tipi di mappe, come TreeMapoLinkedHashMap .


Aggiornamento (2018) : attivato Java 9 o versioni successive, il codice più breve per la creazione di una mappa vuota immutabile è:

Map.of()

... utilizzando i nuovi metodi di fabbrica di convenienza da JEP 269 . 😎


Nella maggior parte dei casi, l'inferenza del tipo funziona (ad es. Map = Collections.emptyMap () funziona)
Sébastien RoccaSerra

Si vero. Ho modificato la risposta per essere un po 'più completa.
Jonik

16

Il problema era che questa mappa può essere applicata solo a un oggetto Map, non a HashMap
JorgeO

7
Dovresti (generalmente) evitare di dichiarare oggetti dei loro tipi specifici e usare invece l'interfaccia (o il genitore astratto). Cerca di evitare "HashMap <String, String> foo;" e usa "Map <String, String> foo;" invece
TofuBeer


10

Se hai bisogno di un'istanza di HashMap, il modo migliore è:

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

Poiché Map è un'interfaccia, è necessario scegliere una classe che ne istanzia l'istanza se si desidera creare un'istanza vuota. HashMap sembra buono come qualsiasi altro, quindi usalo.


7

Oppure Collections.emptyMap(), o se l'inferenza del tipo non funziona nel tuo caso,
Collections.<String, String>emptyMap()


2

Poiché in molti casi viene utilizzata una mappa vuota per la progettazione null-safe, è possibile utilizzare il nullToEmptymetodo di utilità:

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

}  

Allo stesso modo per i set:

class SetUtils {

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

}

ed elenchi:

class ListUtils {

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

}

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.